dolibarr  9.0.0
admin.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2008-2011 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2005-2016 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2012 J. Fernando Lagrange <fernando@demo-tic.org>
5  * Copyright (C) 2015 RaphaĆ«l Doursenaud <rdoursenaud@gpcsolutions.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  * or see http://www.gnu.org/
20  */
21 
27 require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
28 
35 function versiontostring($versionarray)
36 {
37  $string='?';
38  if (isset($versionarray[0])) $string=$versionarray[0];
39  if (isset($versionarray[1])) $string.='.'.$versionarray[1];
40  if (isset($versionarray[2])) $string.='.'.$versionarray[2];
41  return $string;
42 }
43 
58 function versioncompare($versionarray1,$versionarray2)
59 {
60  $ret=0;
61  $level=0;
62  $count1=count($versionarray1);
63  $count2=count($versionarray2);
64  $maxcount=max($count1,$count2);
65  while ($level < $maxcount)
66  {
67  $operande1=isset($versionarray1[$level])?$versionarray1[$level]:0;
68  $operande2=isset($versionarray2[$level])?$versionarray2[$level]:0;
69  if (preg_match('/alpha|dev/i',$operande1)) $operande1=-5;
70  if (preg_match('/alpha|dev/i',$operande2)) $operande2=-5;
71  if (preg_match('/beta$/i',$operande1)) $operande1=-4;
72  if (preg_match('/beta$/i',$operande2)) $operande2=-4;
73  if (preg_match('/beta([0-9])+/i',$operande1)) $operande1=-3;
74  if (preg_match('/beta([0-9])+/i',$operande2)) $operande2=-3;
75  if (preg_match('/rc$/i',$operande1)) $operande1=-2;
76  if (preg_match('/rc$/i',$operande2)) $operande2=-2;
77  if (preg_match('/rc([0-9])+/i',$operande1)) $operande1=-1;
78  if (preg_match('/rc([0-9])+/i',$operande2)) $operande2=-1;
79  $level++;
80  //print 'level '.$level.' '.$operande1.'-'.$operande2.'<br>';
81  if ($operande1 < $operande2) { $ret = -$level; break; }
82  if ($operande1 > $operande2) { $ret = $level; break; }
83  }
84  //print join('.',$versionarray1).'('.count($versionarray1).') / '.join('.',$versionarray2).'('.count($versionarray2).') => '.$ret.'<br>'."\n";
85  return $ret;
86 }
87 
88 
94 function versionphparray()
95 {
96  return explode('.',PHP_VERSION);
97 }
98 
105 {
106  return explode('.',DOL_VERSION);
107 }
108 
109 
130 function run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='', $okerror='default', $linelengthlimit=32768, $nocommentremoval=0, $offsetforchartofaccount=0)
131 {
132  global $db, $conf, $langs, $user;
133 
134  dol_syslog("Admin.lib::run_sql run sql file ".$sqlfile." silent=".$silent." entity=".$entity." usesavepoint=".$usesavepoint." handler=".$handler." okerror=".$okerror, LOG_DEBUG);
135 
136  if (! is_numeric($linelengthlimit))
137  {
138  dol_syslog("Admin.lib::run_sql param linelengthlimit is not a numeric", LOG_ERR);
139  return -1;
140  }
141 
142  $ok=0;
143  $error=0;
144  $i=0;
145  $buffer = '';
146  $arraysql = array();
147 
148  // Get version of database
149  $versionarray=$db->getVersionArray();
150 
151  $fp = fopen($sqlfile,"r");
152  if ($fp)
153  {
154  while (! feof($fp))
155  {
156  // Warning fgets with second parameter that is null or 0 hang.
157  if ($linelengthlimit > 0) $buf = fgets($fp, $linelengthlimit);
158  else $buf = fgets($fp);
159 
160  // Test if request must be ran only for particular database or version (if yes, we must remove the -- comment)
161  if (preg_match('/^--\sV(MYSQL|PGSQL)([^\s]*)/i',$buf,$reg))
162  {
163  $qualified=1;
164 
165  // restrict on database type
166  if (! empty($reg[1]))
167  {
168  if (! preg_match('/'.preg_quote($reg[1]).'/i',$db->type)) $qualified=0;
169  }
170 
171  // restrict on version
172  if ($qualified)
173  {
174  if (! empty($reg[2]))
175  {
176  if (is_numeric($reg[2])) // This is a version
177  {
178  $versionrequest=explode('.',$reg[2]);
179  //print var_dump($versionrequest);
180  //print var_dump($versionarray);
181  if (! count($versionrequest) || ! count($versionarray) || versioncompare($versionrequest,$versionarray) > 0)
182  {
183  $qualified=0;
184  }
185  }
186  else // This is a test on a constant. For example when we have -- VMYSQLUTF8UNICODE, we test constant $conf->global->UTF8UNICODE
187  {
188  $dbcollation = strtoupper(preg_replace('/_/', '', $conf->db->dolibarr_main_db_collation));
189  //var_dump($reg[2]);
190  //var_dump($dbcollation);
191  if (empty($conf->db->dolibarr_main_db_collation) || ($reg[2] != $dbcollation)) $qualified=0;
192  //var_dump($qualified);
193  }
194  }
195  }
196 
197  if ($qualified)
198  {
199  // Version qualified, delete SQL comments
200  $buf=preg_replace('/^--\sV(MYSQL|PGSQL)([^\s]*)/i','',$buf);
201  //print "Ligne $i qualifi?e par version: ".$buf.'<br>';
202  }
203  }
204 
205  // Add line buf to buffer if not a comment
206  if ($nocommentremoval || ! preg_match('/^\s*--/',$buf))
207  {
208  if (empty($nocommentremoval)) $buf=preg_replace('/([,;ERLT\)])\s*--.*$/i','\1',$buf); //remove comment from a line that not start with -- before add it to the buffer
209  $buffer .= trim($buf);
210  }
211 
212  //print $buf.'<br>';exit;
213 
214  if (preg_match('/;/',$buffer)) // If string contains ';', it's end of a request string, we save it in arraysql.
215  {
216  // Found new request
217  if ($buffer) $arraysql[$i]=$buffer;
218  $i++;
219  $buffer='';
220  }
221  }
222 
223  if ($buffer) $arraysql[$i]=$buffer;
224  fclose($fp);
225  }
226  else
227  {
228  dol_syslog("Admin.lib::run_sql failed to open file ".$sqlfile, LOG_ERR);
229  }
230 
231  // Loop on each request to see if there is a __+MAX_table__ key
232  $listofmaxrowid=array(); // This is a cache table
233  foreach($arraysql as $i => $sql)
234  {
235  $newsql=$sql;
236 
237  // Replace __+MAX_table__ with max of table
238  while (preg_match('/__\+MAX_([A-Za-z_]+)__/i',$newsql,$reg))
239  {
240  $table=$reg[1];
241  if (! isset($listofmaxrowid[$table]))
242  {
243  //var_dump($db);
244  $sqlgetrowid='SELECT MAX(rowid) as max from '.preg_replace('/^llx_/', MAIN_DB_PREFIX, $table);
245  $resql=$db->query($sqlgetrowid);
246  if ($resql)
247  {
248  $obj=$db->fetch_object($resql);
249  $listofmaxrowid[$table]=$obj->max;
250  if (empty($listofmaxrowid[$table])) $listofmaxrowid[$table]=0;
251  }
252  else
253  {
254  if (! $silent) print '<tr><td valign="top" colspan="2">';
255  if (! $silent) print '<div class="error">'.$langs->trans("Failed to get max rowid for ".$table)."</div></td>";
256  if (! $silent) print '</tr>';
257  $error++;
258  break;
259  }
260  }
261  // Replace __+MAX_llx_table__ with +999
262  $from='__+MAX_'.$table.'__';
263  $to='+'.$listofmaxrowid[$table];
264  $newsql=str_replace($from, $to, $newsql);
265  dol_syslog('Admin.lib::run_sql New Request '.($i+1).' (replacing '.$from.' to '.$to.')', LOG_DEBUG);
266 
267  $arraysql[$i]=$newsql;
268  }
269 
270  if ($offsetforchartofaccount > 0)
271  {
272  // Replace lines
273  // 'INSERT INTO llx_accounting_account (__ENTITY__, rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (1401, 'PCG99-ABREGE','CAPIT', 'XXXXXX', '1', 0, '...', 1);'
274  // with
275  // 'INSERT INTO llx_accounting_account (__ENTITY__, rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (1401 + 200100000, 'PCG99-ABREGE','CAPIT', 'XXXXXX', '1', 0, '...', 1);'
276  $newsql = preg_replace('/VALUES\s*\(__ENTITY__, \s*(\d+)\s*,(\s*\'[^\',]*\'\s*,\s*\'[^\',]*\'\s*,\s*\'[^\',]*\'\s*,\s*\'[^\',]*\'\s*),\s*\'?([^\',]*)\'?/ims', 'VALUES (__ENTITY__, \1 + '.$offsetforchartofaccount.', \2, \3 + '.$offsetforchartofaccount, $newsql);
277  $newsql = preg_replace('/([,\s])0 \+ '.$offsetforchartofaccount.'/ims', '\1 0', $newsql);
278  //var_dump($newsql);
279  $arraysql[$i] = $newsql;
280  }
281  }
282 
283  // Loop on each request to execute request
284  $cursorinsert=0;
285  $listofinsertedrowid=array();
286  foreach($arraysql as $i => $sql)
287  {
288  if ($sql)
289  {
290  // Replace the prefix tables
291  if (MAIN_DB_PREFIX != 'llx_')
292  {
293  $sql=preg_replace('/llx_/i',MAIN_DB_PREFIX,$sql);
294  }
295 
296  if (!empty($handler)) $sql=preg_replace('/__HANDLER__/i',"'".$handler."'",$sql);
297 
298  $newsql=preg_replace('/__ENTITY__/i',(!empty($entity)?$entity:$conf->entity),$sql);
299 
300  // Ajout trace sur requete (eventuellement a commenter si beaucoup de requetes)
301  if (! $silent) print '<tr><td class="tdtop">'.$langs->trans("Request").' '.($i+1)." sql='".dol_htmlentities($newsql,ENT_NOQUOTES)."'</td></tr>\n";
302  dol_syslog('Admin.lib::run_sql Request '.($i+1), LOG_DEBUG);
303  $sqlmodified=0;
304 
305  // Replace for encrypt data
306  if (preg_match_all('/__ENCRYPT\(\'([^\']+)\'\)__/i',$newsql,$reg))
307  {
308  $num=count($reg[0]);
309 
310  for($j=0;$j<$num;$j++)
311  {
312  $from = $reg[0][$j];
313  $to = $db->encrypt($reg[1][$j],1);
314  $newsql = str_replace($from,$to,$newsql);
315  }
316  $sqlmodified++;
317  }
318 
319  // Replace for decrypt data
320  if (preg_match_all('/__DECRYPT\(\'([A-Za-z0-9_]+)\'\)__/i',$newsql,$reg))
321  {
322  $num=count($reg[0]);
323 
324  for($j=0;$j<$num;$j++)
325  {
326  $from = $reg[0][$j];
327  $to = $db->decrypt($reg[1][$j]);
328  $newsql = str_replace($from,$to,$newsql);
329  }
330  $sqlmodified++;
331  }
332 
333  // Replace __x__ with rowid of insert nb x
334  while (preg_match('/__([0-9]+)__/',$newsql,$reg))
335  {
336  $cursor=$reg[1];
337  if (empty($listofinsertedrowid[$cursor]))
338  {
339  if (! $silent) print '<tr><td valign="top" colspan="2">';
340  if (! $silent) print '<div class="error">'.$langs->trans("FileIsNotCorrect")."</div></td>";
341  if (! $silent) print '</tr>';
342  $error++;
343  break;
344  }
345  $from='__'.$cursor.'__';
346  $to=$listofinsertedrowid[$cursor];
347  $newsql=str_replace($from,$to,$newsql);
348  $sqlmodified++;
349  }
350 
351  if ($sqlmodified) dol_syslog('Admin.lib::run_sql New Request '.($i+1), LOG_DEBUG);
352 
353  $result=$db->query($newsql,$usesavepoint);
354  if ($result)
355  {
356  if (! $silent) print '<!-- Result = OK -->'."\n";
357 
358  if (preg_replace('/insert into ([^\s]+)/i',$newsql,$reg))
359  {
360  $cursorinsert++;
361 
362  // It's an insert
363  $table=preg_replace('/([^a-zA-Z_]+)/i','',$reg[1]);
364  $insertedrowid=$db->last_insert_id($table);
365  $listofinsertedrowid[$cursorinsert]=$insertedrowid;
366  dol_syslog('Admin.lib::run_sql Insert nb '.$cursorinsert.', done in table '.$table.', rowid is '.$listofinsertedrowid[$cursorinsert], LOG_DEBUG);
367  }
368  // print '<td align="right">OK</td>';
369  }
370  else
371  {
372  $errno=$db->errno();
373  if (! $silent) print '<!-- Result = '.$errno.' -->'."\n";
374 
375  // Define list of errors we accept (array $okerrors)
376  $okerrors=array( // By default
377  'DB_ERROR_TABLE_ALREADY_EXISTS',
378  'DB_ERROR_COLUMN_ALREADY_EXISTS',
379  'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
380  'DB_ERROR_TABLE_OR_KEY_ALREADY_EXISTS', // PgSql use same code for table and key already exist
381  'DB_ERROR_RECORD_ALREADY_EXISTS',
382  'DB_ERROR_NOSUCHTABLE',
383  'DB_ERROR_NOSUCHFIELD',
384  'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
385  'DB_ERROR_NO_INDEX_TO_DROP',
386  'DB_ERROR_CANNOT_CREATE', // Qd contrainte deja existante
387  'DB_ERROR_CANT_DROP_PRIMARY_KEY',
388  'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
389  'DB_ERROR_22P02'
390  );
391  if ($okerror == 'none') $okerrors=array();
392 
393  // Is it an error we accept
394  if (! in_array($errno,$okerrors))
395  {
396  if (! $silent) print '<tr><td valign="top" colspan="2">';
397  if (! $silent) print '<div class="error">'.$langs->trans("Error")." ".$db->errno().": ".$newsql."<br>".$db->error()."</div></td>";
398  if (! $silent) print '</tr>'."\n";
399  dol_syslog('Admin.lib::run_sql Request '.($i+1)." Error ".$db->errno()." ".$newsql."<br>".$db->error(), LOG_ERR);
400  $error++;
401  }
402  }
403 
404  if (! $silent) print '</tr>'."\n";
405  }
406  }
407 
408  if ($error == 0)
409  {
410  if (! $silent) print '<tr><td>'.$langs->trans("ProcessMigrateScript").'</td>';
411  if (! $silent) print '<td align="right">'.$langs->trans("OK").'</td></tr>'."\n";
412  $ok = 1;
413  }
414  else
415  {
416  if (! $silent) print '<tr><td>'.$langs->trans("ProcessMigrateScript").'</td>';
417  if (! $silent) print '<td align="right"><font class="error">'.$langs->trans("KO").'</font></td></tr>'."\n";
418  $ok = 0;
419  }
420 
421  return $ok;
422 }
423 
424 
435 function dolibarr_del_const($db, $name, $entity=1)
436 {
437  global $conf;
438 
439  if (empty($name))
440  {
441  dol_print_error('','Error call dolibar_del_const with parameter name empty');
442  return -1;
443  }
444 
445  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
446  $sql.= " WHERE (".$db->decrypt('name')." = '".$db->escape($name)."'";
447  if (is_numeric($name)) $sql.= " OR rowid = '".$db->escape($name)."'";
448  $sql.= ")";
449  if ($entity >= 0) $sql.= " AND entity = ".$entity;
450 
451  dol_syslog("admin.lib::dolibarr_del_const", LOG_DEBUG);
452  $resql=$db->query($sql);
453  if ($resql)
454  {
455  $conf->global->$name='';
456  return 1;
457  }
458  else
459  {
460  dol_print_error($db);
461  return -1;
462  }
463 }
464 
475 function dolibarr_get_const($db, $name, $entity=1)
476 {
477  global $conf;
478  $value='';
479 
480  $sql = "SELECT ".$db->decrypt('value')." as value";
481  $sql.= " FROM ".MAIN_DB_PREFIX."const";
482  $sql.= " WHERE name = ".$db->encrypt($name,1);
483  $sql.= " AND entity = ".$entity;
484 
485  dol_syslog("admin.lib::dolibarr_get_const", LOG_DEBUG);
486  $resql=$db->query($sql);
487  if ($resql)
488  {
489  $obj=$db->fetch_object($resql);
490  if ($obj) $value=$obj->value;
491  }
492  return $value;
493 }
494 
495 
510 function dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
511 {
512  global $conf;
513 
514  // Clean parameters
515  $name=trim($name);
516 
517  // Check parameters
518  if (empty($name))
519  {
520  dol_print_error($db,"Error: Call to function dolibarr_set_const with wrong parameters", LOG_ERR);
521  exit;
522  }
523 
524  //dol_syslog("dolibarr_set_const name=$name, value=$value type=$type, visible=$visible, note=$note entity=$entity");
525 
526  $db->begin();
527 
528  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
529  $sql.= " WHERE name = ".$db->encrypt($name,1);
530  if ($entity >= 0) $sql.= " AND entity = ".$entity;
531 
532  dol_syslog("admin.lib::dolibarr_set_const", LOG_DEBUG);
533  $resql=$db->query($sql);
534 
535  if (strcmp($value,'')) // true if different. Must work for $value='0' or $value=0
536  {
537  $sql = "INSERT INTO ".MAIN_DB_PREFIX."const(name,value,type,visible,note,entity)";
538  $sql.= " VALUES (";
539  $sql.= $db->encrypt($name,1);
540  $sql.= ", ".$db->encrypt($value,1);
541  $sql.= ",'".$db->escape($type)."',".$visible.",'".$db->escape($note)."',".$entity.")";
542 
543  //print "sql".$value."-".pg_escape_string($value)."-".$sql;exit;
544  //print "xx".$db->escape($value);
545  dol_syslog("admin.lib::dolibarr_set_const", LOG_DEBUG);
546  $resql=$db->query($sql);
547  }
548 
549  if ($resql)
550  {
551  $db->commit();
552  $conf->global->$name=$value;
553  return 1;
554  }
555  else
556  {
557  $error=$db->lasterror();
558  $db->rollback();
559  return -1;
560  }
561 }
562 
563 
564 
565 
572 {
573  global $langs, $conf, $user;
574  $h = 0;
575  $head = array();
576 
577  $head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=common";
578  $head[$h][1] = $langs->trans("AvailableModules");
579  $head[$h][2] = 'common';
580  $h++;
581 
582  $head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=marketplace";
583  $head[$h][1] = $langs->trans("ModulesMarketPlaces");
584  $head[$h][2] = 'marketplace';
585  $h++;
586 
587  $head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=deploy";
588  $head[$h][1] = $langs->trans("AddExtensionThemeModuleOrOther");
589  $head[$h][2] = 'deploy';
590  $h++;
591 
592  $head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=develop";
593  $head[$h][1] = $langs->trans("ModulesDevelopYourModule");
594  $head[$h][2] = 'develop';
595  $h++;
596 
597  return $head;
598 }
599 
600 
607 {
608  global $db, $langs, $conf, $user;
609  $h = 0;
610  $head = array();
611 
612  $head[$h][0] = DOL_URL_ROOT."/admin/security_other.php";
613  $head[$h][1] = $langs->trans("Miscellaneous");
614  $head[$h][2] = 'misc';
615  $h++;
616 
617  $head[$h][0] = DOL_URL_ROOT."/admin/security.php";
618  $head[$h][1] = $langs->trans("Passwords");
619  $head[$h][2] = 'passwords';
620  $h++;
621 
622  $head[$h][0] = DOL_URL_ROOT."/admin/security_file.php";
623  $head[$h][1] = $langs->trans("Files").' ('.$langs->trans("Upload").')';
624  $head[$h][2] = 'file';
625  $h++;
626 
627  /*
628  $head[$h][0] = DOL_URL_ROOT."/admin/security_file_download.php";
629  $head[$h][1] = $langs->trans("Files").' ('.$langs->trans("Download").')';
630  $head[$h][2] = 'filedownload';
631  $h++;
632  */
633 
634  $head[$h][0] = DOL_URL_ROOT."/admin/proxy.php";
635  $head[$h][1] = $langs->trans("ExternalAccess");
636  $head[$h][2] = 'proxy';
637  $h++;
638 
639  $head[$h][0] = DOL_URL_ROOT."/admin/events.php";
640  $head[$h][1] = $langs->trans("Audit");
641  $head[$h][2] = 'audit';
642  $h++;
643 
644 
645  // Show permissions lines
646  $nbPerms=0;
647  $sql = "SELECT COUNT(r.id) as nb";
648  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def as r";
649  $sql.= " WHERE r.libelle NOT LIKE 'tou%'"; // On ignore droits "tous"
650  $sql.= " AND entity = ".$conf->entity;
651  $sql.= " AND bydefault = 1";
652  if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) $sql.= " AND r.perms NOT LIKE '%_advance'"; // Hide advanced perms if option is not enabled
653  $resql = $db->query($sql);
654  if ($resql)
655  {
656  $obj = $db->fetch_object($resql);
657  if ($obj) $nbPerms = $obj->nb;
658  }
659  else dol_print_error($db);
660 
661  $head[$h][0] = DOL_URL_ROOT."/admin/perms.php";
662  $head[$h][1] = $langs->trans("DefaultRights");
663  if ($nbPerms > 0) $head[$h][1].= ' <span class="badge">'.$nbPerms.'</span>';
664  $head[$h][2] = 'default';
665  $h++;
666 
667  return $head;
668 }
669 
670 
677 {
678  global $langs, $conf, $user;
679  $h = 0;
680  $head = array();
681 
682  $head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=overwrite";
683  $head[$h][1] = $langs->trans("TranslationOverwriteKey");
684  $head[$h][2] = 'overwrite';
685  $h++;
686 
687  $head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=searchkey";
688  $head[$h][1] = $langs->trans("TranslationKeySearch");
689  $head[$h][2] = 'searchkey';
690  $h++;
691 
692  complete_head_from_modules($conf,$langs,null,$head,$h,'translation_admin');
693 
694  complete_head_from_modules($conf,$langs,null,$head,$h,'translation_admin','remove');
695 
696 
697  return $head;
698 }
699 
700 
707 {
708  global $langs, $conf, $user;
709  $h = 0;
710  $head = array();
711 
712  $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=createform";
713  $head[$h][1] = $langs->trans("DefaultCreateForm");
714  $head[$h][2] = 'createform';
715  $h++;
716 
717  $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=filters";
718  $head[$h][1] = $langs->trans("DefaultSearchFilters");
719  $head[$h][2] = 'filters';
720  $h++;
721 
722  $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=sortorder";
723  $head[$h][1] = $langs->trans("DefaultSortOrder");
724  $head[$h][2] = 'sortorder';
725  $h++;
726 
727  if (! empty($conf->use_javascript_ajax))
728  {
729  $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=focus";
730  $head[$h][1] = $langs->trans("DefaultFocus");
731  $head[$h][2] = 'focus';
732  $h++;
733 
734  $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=mandatory";
735  $head[$h][1] = $langs->trans("DefaultMandatory");
736  $head[$h][2] = 'mandatory';
737  $h++;
738  }
739 
740  /*$head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=searchkey";
741  $head[$h][1] = $langs->trans("TranslationKeySearch");
742  $head[$h][2] = 'searchkey';
743  $h++;*/
744 
745  complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin');
746 
747  complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin','remove');
748 
749 
750  return $head;
751 }
752 
753 
759 function listOfSessions()
760 {
761  global $conf;
762 
763  $arrayofSessions = array();
764  // session.save_path can be returned empty so we set a default location and work from there
765  $sessPath = '/tmp';
766  $iniPath = ini_get("session.save_path");
767  if ($iniPath) {
768  $sessPath = $iniPath;
769  }
770  $sessPath .= '/'; // We need the trailing slash
771  dol_syslog('admin.lib:listOfSessions sessPath='.$sessPath);
772 
773  $dh = @opendir(dol_osencode($sessPath));
774  if ($dh)
775  {
776  while(($file = @readdir($dh)) !== false)
777  {
778  if (preg_match('/^sess_/i',$file) && $file != "." && $file != "..")
779  {
780  $fullpath = $sessPath.$file;
781  if(! @is_dir($fullpath) && is_readable($fullpath))
782  {
783  $sessValues = file_get_contents($fullpath); // get raw session data
784  // Example of possible value
785  //$sessValues = 'newtoken|s:32:"1239f7a0c4b899200fe9ca5ea394f307";dol_loginmesg|s:0:"";newtoken|s:32:"1236457104f7ae0f328c2928973f3cb5";dol_loginmesg|s:0:"";token|s:32:"123615ad8d650c5cc4199b9a1a76783f";
786  // dol_login|s:5:"admin";dol_authmode|s:8:"dolibarr";dol_tz|s:1:"1";dol_tz_string|s:13:"Europe/Berlin";dol_dst|i:0;dol_dst_observed|s:1:"1";dol_dst_first|s:0:"";dol_dst_second|s:0:"";dol_screenwidth|s:4:"1920";
787  // dol_screenheight|s:3:"971";dol_company|s:12:"MyBigCompany";dol_entity|i:1;mainmenu|s:4:"home";leftmenuopened|s:10:"admintools";idmenu|s:0:"";leftmenu|s:10:"admintools";';
788 
789  if (preg_match('/dol_login/i',$sessValues) && // limit to dolibarr session
790  (preg_match('/dol_entity\|i:'.$conf->entity.';/i',$sessValues) || preg_match('/dol_entity\|s:([0-9]+):"'.$conf->entity.'"/i',$sessValues)) && // limit to current entity
791  preg_match('/dol_company\|s:([0-9]+):"('.$conf->global->MAIN_INFO_SOCIETE_NOM.')"/i',$sessValues)) // limit to company name
792  {
793  $tmp=explode('_', $file);
794  $idsess=$tmp[1];
795  $login = preg_match('/dol_login\|s:[0-9]+:"([A-Za-z0-9]+)"/i',$sessValues,$regs);
796  $arrayofSessions[$idsess]["login"] = $regs[1];
797  $arrayofSessions[$idsess]["age"] = time()-filectime($fullpath);
798  $arrayofSessions[$idsess]["creation"] = filectime($fullpath);
799  $arrayofSessions[$idsess]["modification"] = filemtime($fullpath);
800  $arrayofSessions[$idsess]["raw"] = $sessValues;
801  }
802  }
803  }
804  }
805  @closedir($dh);
806  }
807 
808  return $arrayofSessions;
809 }
810 
817 function purgeSessions($mysessionid)
818 {
819  global $conf;
820 
821  $arrayofSessions = array();
822  $sessPath = ini_get("session.save_path")."/";
823  dol_syslog('admin.lib:purgeSessions mysessionid='.$mysessionid.' sessPath='.$sessPath);
824 
825  $error=0;
826  $dh = @opendir(dol_osencode($sessPath));
827  while(($file = @readdir($dh)) !== false)
828  {
829  if ($file != "." && $file != "..")
830  {
831  $fullpath = $sessPath.$file;
832  if(! @is_dir($fullpath))
833  {
834  $sessValues = file_get_contents($fullpath); // get raw session data
835 
836  if (preg_match('/dol_login/i',$sessValues) && // limit to dolibarr session
837  preg_match('/dol_entity\|s:([0-9]+):"('.$conf->entity.')"/i',$sessValues) && // limit to current entity
838  preg_match('/dol_company\|s:([0-9]+):"('.$conf->global->MAIN_INFO_SOCIETE_NOM.')"/i',$sessValues)) // limit to company name
839  {
840  $tmp=explode('_', $file);
841  $idsess=$tmp[1];
842  // We remove session if it's not ourself
843  if ($idsess != $mysessionid)
844  {
845  $res=@unlink($fullpath);
846  if (! $res) $error++;
847  }
848  }
849  }
850  }
851  }
852  @closedir($dh);
853 
854  if (! $error) return 1;
855  else return -$error;
856 }
857 
858 
859 
867 function activateModule($value,$withdeps=1)
868 {
869  global $db, $modules, $langs, $conf, $mysoc;
870 
871  // Check parameters
872  if (empty($value)) {
873  $ret['errors'][] = 'ErrorBadParameter';
874  return $ret;
875  }
876 
877  $ret=array('nbmodules'=>0, 'errors'=>array(), 'nbperms'=>0);
878  $modName = $value;
879  $modFile = $modName . ".class.php";
880 
881  // Loop on each directory to fill $modulesdir
882  $modulesdir = dolGetModulesDirs();
883 
884  // Loop on each modulesdir directories
885  $found=false;
886  foreach ($modulesdir as $dir)
887  {
888  if (file_exists($dir.$modFile))
889  {
890  $found=@include_once $dir.$modFile;
891  if ($found) break;
892  }
893  }
894 
895  $objMod = new $modName($db);
896 
897  // Test if PHP version ok
898  $verphp=versionphparray();
899  $vermin=isset($objMod->phpmin)?$objMod->phpmin:0;
900  if (is_array($vermin) && versioncompare($verphp, $vermin) < 0) {
901  $ret['errors'][] = $langs->trans("ErrorModuleRequirePHPVersion", versiontostring($vermin));
902  return $ret;
903  }
904 
905  // Test if Dolibarr version ok
906  $verdol=versiondolibarrarray();
907  $vermin=isset($objMod->need_dolibarr_version)?$objMod->need_dolibarr_version:0;
908  //print 'version: '.versioncompare($verdol,$vermin).' - '.join(',',$verdol).' - '.join(',',$vermin);exit;
909  if (is_array($vermin) && versioncompare($verdol, $vermin) < 0) {
910  $ret['errors'][] = $langs->trans("ErrorModuleRequireDolibarrVersion", versiontostring($vermin));
911  return $ret;
912  }
913 
914  // Test if javascript requirement ok
915  if (!empty($objMod->need_javascript_ajax) && empty($conf->use_javascript_ajax)) {
916  $ret['errors'][] = $langs->trans("ErrorModuleRequireJavascript");
917  return $ret;
918  }
919 
920  $const_name = $objMod->const_name;
921  if(!empty($conf->global->$const_name)){
922  return $ret;
923  }
924 
925  $result=$objMod->init(); // Enable module
926 
927  if ($result <= 0)
928  {
929  $ret['errors'][]=$objMod->error;
930  }
931  else
932  {
933  if ($withdeps)
934  {
935  if (isset($objMod->depends) && is_array($objMod->depends) && ! empty($objMod->depends))
936  {
937  // Activation of modules this module depends on
938  // this->depends may be array('modModule1', 'mmodModule2') or array('always1'=>"modModule1", 'FR'=>'modModule2')
939  foreach ($objMod->depends as $key => $modulestring)
940  {
941  //var_dump((! is_numeric($key)) && ! preg_match('/^always/', $key) && $mysoc->country_code && ! preg_match('/^'.$mysoc->country_code.'/', $key));exit;
942  if ((! is_numeric($key)) && ! preg_match('/^always/', $key) && $mysoc->country_code && ! preg_match('/^'.$mysoc->country_code.'/', $key))
943  {
944  dol_syslog("We are not concerned by dependency with key=".$key." because our country is ".$mysoc->country_code);
945  continue;
946  }
947  $activate = false;
948  foreach ($modulesdir as $dir)
949  {
950  if (file_exists($dir.$modulestring.".class.php"))
951  {
952  $resarray = activateModule($modulestring);
953  if (empty($resarray['errors'])){
954  $activate = true;
955  }else{
956  foreach ($resarray['errors'] as $errorMessage){
957  dol_syslog($errorMessage, LOG_ERR);
958  }
959  }
960  break;
961  }
962  }
963 
964  if ($activate)
965  {
966  $ret['nbmodules']+=$resarray['nbmodules'];
967  $ret['nbperms']+=$resarray['nbperms'];
968  }
969  else
970  {
971  $ret['errors'][] = $langs->trans('activateModuleDependNotSatisfied', $objMod->name, $modulestring);
972  }
973  }
974  }
975 
976  if (isset($objMod->conflictwith) && is_array($objMod->conflictwith) && ! empty($objMod->conflictwith))
977  {
978  // Desactivation des modules qui entrent en conflit
979  $num = count($objMod->conflictwith);
980  for ($i = 0; $i < $num; $i++)
981  {
982  foreach ($modulesdir as $dir)
983  {
984  if (file_exists($dir.$objMod->conflictwith[$i].".class.php"))
985  {
986  unActivateModule($objMod->conflictwith[$i],0);
987  }
988  }
989  }
990  }
991  }
992  }
993 
994  if (! count($ret['errors']))
995  {
996  $ret['nbmodules']++;
997  $ret['nbperms']+=count($objMod->rights);
998  }
999 
1000  return $ret;
1001 }
1002 
1003 
1011 function unActivateModule($value, $requiredby=1)
1012 {
1013  global $db, $modules, $conf;
1014 
1015  // Check parameters
1016  if (empty($value)) return 'ErrorBadParameter';
1017 
1018  $ret='';
1019  $modName = $value;
1020  $modFile = $modName . ".class.php";
1021 
1022  // Loop on each directory to fill $modulesdir
1023  $modulesdir = dolGetModulesDirs();
1024 
1025  // Loop on each modulesdir directories
1026  $found=false;
1027  foreach ($modulesdir as $dir)
1028  {
1029  if (file_exists($dir.$modFile))
1030  {
1031  $found=@include_once $dir.$modFile;
1032  if ($found) break;
1033  }
1034  }
1035 
1036  if ($found)
1037  {
1038  $objMod = new $modName($db);
1039  $result=$objMod->remove();
1040  if ($result <= 0) $ret=$objMod->error;
1041  }
1042  else
1043  {
1044  //print $dir.$modFile;
1045  // TODO Replace this after DolibarrModules is moved as abstract class with a try catch to show module we try to disable has not been found or could not be loaded
1046  include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
1047  $genericMod = new DolibarrModules($db);
1048  $genericMod->name=preg_replace('/^mod/i','',$modName);
1049  $genericMod->rights_class=strtolower(preg_replace('/^mod/i','',$modName));
1050  $genericMod->const_name='MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',$modName));
1051  dol_syslog("modules::unActivateModule Failed to find module file, we use generic function with name " . $modName);
1052  $genericMod->_remove(array());
1053  }
1054 
1055  // Desactivation des modules qui dependent de lui
1056  if (! $ret && $requiredby)
1057  {
1058  $countrb=count($objMod->requiredby);
1059  for ($i = 0; $i < $countrb; $i++)
1060  {
1061  //var_dump($objMod->requiredby[$i]);
1062  unActivateModule($objMod->requiredby[$i]);
1063  }
1064  }
1065 
1066  return $ret;
1067 }
1068 
1069 
1088 function complete_dictionary_with_modules(&$taborder,&$tabname,&$tablib,&$tabsql,&$tabsqlsort,&$tabfield,&$tabfieldvalue,&$tabfieldinsert,&$tabrowid,&$tabcond,&$tabhelp,&$tabfieldcheck)
1089 {
1090  global $db, $modules, $conf, $langs;
1091 
1092  // Search modules
1093  $modulesdir = dolGetModulesDirs();
1094  $i = 0; // is a sequencer of modules found
1095  $j = 0; // j is module number. Automatically affected if module number not defined.
1096 
1097  foreach ($modulesdir as $dir)
1098  {
1099  // Load modules attributes in arrays (name, numero, orders) from dir directory
1100  //print $dir."\n<br>";
1101  dol_syslog("Scan directory ".$dir." for modules");
1102  $handle=@opendir(dol_osencode($dir));
1103  if (is_resource($handle))
1104  {
1105  while (($file = readdir($handle))!==false)
1106  {
1107  //print "$i ".$file."\n<br>";
1108  if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php')
1109  {
1110  $modName = substr($file, 0, dol_strlen($file) - 10);
1111 
1112  if ($modName)
1113  {
1114  include_once $dir.$file;
1115  $objMod = new $modName($db);
1116 
1117  if ($objMod->numero > 0)
1118  {
1119  $j = $objMod->numero;
1120  }
1121  else
1122  {
1123  $j = 1000 + $i;
1124  }
1125 
1126  $modulequalified=1;
1127 
1128  // We discard modules according to features level (PS: if module is activated we always show it)
1129  $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
1130  if ($objMod->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2 && ! $conf->global->$const_name) $modulequalified=0;
1131  if ($objMod->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1 && ! $conf->global->$const_name) $modulequalified=0;
1132  //If module is not activated disqualified
1133  if (empty($conf->global->$const_name)) $modulequalified=0;
1134 
1135  if ($modulequalified)
1136  {
1137  // Load languages files of module
1138  if (isset($objMod->langfiles) && is_array($objMod->langfiles)) {
1139  foreach ($objMod->langfiles as $langfile) {
1140  $langs->load($langfile);
1141  }
1142  }
1143 
1144  // Complete the arrays &$tabname,&$tablib,&$tabsql,&$tabsqlsort,&$tabfield,&$tabfieldvalue,&$tabfieldinsert,&$tabrowid,&$tabcond
1145  if (empty($objMod->dictionaries) && ! empty($objMod->dictionnaries)) $objMod->dictionaries=$objMod->dictionnaries; // For backward compatibility
1146 
1147  if (! empty($objMod->dictionaries))
1148  {
1149  //var_dump($objMod->dictionaries['tabname']);
1150  $nbtabname=$nbtablib=$nbtabsql=$nbtabsqlsort=$nbtabfield=$nbtabfieldvalue=$nbtabfieldinsert=$nbtabrowid=$nbtabcond=$nbtabfieldcheck=$nbtabhelp=0;
1151  foreach($objMod->dictionaries['tabname'] as $val) { $nbtabname++; $taborder[] = max($taborder)+1; $tabname[] = $val; } // Position
1152  foreach($objMod->dictionaries['tablib'] as $val) { $nbtablib++; $tablib[] = $val; }
1153  foreach($objMod->dictionaries['tabsql'] as $val) { $nbtabsql++; $tabsql[] = $val; }
1154  foreach($objMod->dictionaries['tabsqlsort'] as $val) { $nbtabsqlsort++; $tabsqlsort[] = $val; }
1155  foreach($objMod->dictionaries['tabfield'] as $val) { $nbtabfield++; $tabfield[] = $val; }
1156  foreach($objMod->dictionaries['tabfieldvalue'] as $val) { $nbtabfieldvalue++; $tabfieldvalue[] = $val; }
1157  foreach($objMod->dictionaries['tabfieldinsert'] as $val) { $nbtabfieldinsert++; $tabfieldinsert[] = $val; }
1158  foreach($objMod->dictionaries['tabrowid'] as $val) { $nbtabrowid++; $tabrowid[] = $val; }
1159  foreach($objMod->dictionaries['tabcond'] as $val) { $nbtabcond++; $tabcond[] = $val; }
1160  if (! empty($objMod->dictionaries['tabhelp'])) foreach($objMod->dictionaries['tabhelp'] as $val) { $nbtabhelp++; $tabhelp[] = $val; }
1161  if (! empty($objMod->dictionaries['tabfieldcheck'])) foreach($objMod->dictionaries['tabfieldcheck'] as $val) { $nbtabfieldcheck++; $tabfieldcheck[] = $val; }
1162 
1163  if ($nbtabname != $nbtablib || $nbtablib != $nbtabsql || $nbtabsql != $nbtabsqlsort)
1164  {
1165  print 'Error in descriptor of module '.$const_name.'. Array ->dictionaries has not same number of record for key "tabname", "tablib", "tabsql" and "tabsqlsort"';
1166  //print "$const_name: $nbtabname=$nbtablib=$nbtabsql=$nbtabsqlsort=$nbtabfield=$nbtabfieldvalue=$nbtabfieldinsert=$nbtabrowid=$nbtabcond=$nbtabfieldcheck=$nbtabhelp\n";
1167  }
1168  else
1169  {
1170  $taborder[] = 0; // Add an empty line
1171  }
1172  }
1173 
1174  $j++;
1175  $i++;
1176  }
1177  else dol_syslog("Module ".get_class($objMod)." not qualified");
1178  }
1179  }
1180  }
1181  closedir($handle);
1182  }
1183  else
1184  {
1185  dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
1186  }
1187  }
1188 
1189  return 1;
1190 }
1191 
1198 function activateModulesRequiredByCountry($country_code)
1199 {
1200  global $db, $conf, $langs;
1201 
1202  $modulesdir = dolGetModulesDirs();
1203 
1204  foreach ($modulesdir as $dir)
1205  {
1206  // Load modules attributes in arrays (name, numero, orders) from dir directory
1207  dol_syslog("Scan directory ".$dir." for modules");
1208  $handle=@opendir(dol_osencode($dir));
1209  if (is_resource($handle))
1210  {
1211  while (($file = readdir($handle))!==false)
1212  {
1213  if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php')
1214  {
1215  $modName = substr($file, 0, dol_strlen($file) - 10);
1216 
1217  if ($modName)
1218  {
1219  include_once $dir.$file;
1220  $objMod = new $modName($db);
1221 
1222  $modulequalified=1;
1223 
1224  // We discard modules according to features level (PS: if module is activated we always show it)
1225  $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
1226 
1227  if ($objMod->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0;
1228  if ($objMod->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0;
1229  if(!empty($conf->global->$const_name)) $modulequalified=0; // already activated
1230 
1231  if ($modulequalified)
1232  {
1233  // Load languages files of module
1234  if (isset($objMod->automatic_activation) && is_array($objMod->automatic_activation) && isset($objMod->automatic_activation[$country_code]))
1235  {
1236  activateModule($modName);
1237 
1238  setEventMessages($objMod->automatic_activation[$country_code], null, 'warnings');
1239  }
1240  }
1241  else dol_syslog("Module ".get_class($objMod)." not qualified");
1242  }
1243  }
1244  }
1245  closedir($handle);
1246  }
1247  else
1248  {
1249  dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
1250  }
1251  }
1252 
1253  return 1;
1254 }
1255 
1262 function complete_elementList_with_modules(&$elementList)
1263 {
1264  global $db, $modules, $conf, $langs;
1265 
1266  // Search modules
1267  $filename = array();
1268  $modules = array();
1269  $orders = array();
1270  $categ = array();
1271  $dirmod = array();
1272 
1273  $i = 0; // is a sequencer of modules found
1274  $j = 0; // j is module number. Automatically affected if module number not defined.
1275 
1276  $modulesdir = dolGetModulesDirs();
1277 
1278  foreach ($modulesdir as $dir)
1279  {
1280  // Load modules attributes in arrays (name, numero, orders) from dir directory
1281  //print $dir."\n<br>";
1282  dol_syslog("Scan directory ".$dir." for modules");
1283  $handle=@opendir(dol_osencode($dir));
1284  if (is_resource($handle))
1285  {
1286  while (($file = readdir($handle))!==false)
1287  {
1288  //print "$i ".$file."\n<br>";
1289  if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php')
1290  {
1291  $modName = substr($file, 0, dol_strlen($file) - 10);
1292 
1293  if ($modName)
1294  {
1295  include_once $dir.$file;
1296  $objMod = new $modName($db);
1297 
1298  if ($objMod->numero > 0)
1299  {
1300  $j = $objMod->numero;
1301  }
1302  else
1303  {
1304  $j = 1000 + $i;
1305  }
1306 
1307  $modulequalified=1;
1308 
1309  // We discard modules according to features level (PS: if module is activated we always show it)
1310  $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
1311  if ($objMod->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2 && ! $conf->global->$const_name) $modulequalified=0;
1312  if ($objMod->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1 && ! $conf->global->$const_name) $modulequalified=0;
1313  //If module is not activated disqualified
1314  if (empty($conf->global->$const_name)) $modulequalified=0;
1315 
1316  if ($modulequalified)
1317  {
1318  // Load languages files of module
1319  if (isset($objMod->langfiles) && is_array($objMod->langfiles))
1320  {
1321  foreach($objMod->langfiles as $langfile)
1322  {
1323  $langs->load($langfile);
1324  }
1325  }
1326 
1327  $modules[$i] = $objMod;
1328  $filename[$i]= $modName;
1329  $orders[$i] = $objMod->family."_".$j; // Sort on family then module number
1330  $dirmod[$i] = $dir;
1331  //print "x".$modName." ".$orders[$i]."\n<br>";
1332 
1333  if (! empty($objMod->module_parts['contactelement']))
1334  {
1335  $elementList[$objMod->name] = $langs->trans($objMod->name);
1336  }
1337 
1338  $j++;
1339  $i++;
1340  }
1341  else dol_syslog("Module ".get_class($objMod)." not qualified");
1342  }
1343  }
1344  }
1345  closedir($handle);
1346  }
1347  else
1348  {
1349  dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
1350  }
1351  }
1352 
1353  return 1;
1354 }
1355 
1365 function form_constantes($tableau, $strictw3c=0, $helptext='')
1366 {
1367  global $db,$bc,$langs,$conf,$user;
1368  global $_Avery_Labels;
1369 
1370  $form = new Form($db);
1371 
1372  if (! empty($strictw3c) && $strictw3c == 1) print "\n".'<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1373 
1374  print '<table class="noborder" width="100%">';
1375  print '<tr class="liste_titre">';
1376  print '<td class="titlefield">'.$langs->trans("Description").'</td>';
1377  print '<td>';
1378  $text = $langs->trans("Value");
1379  print $form->textwithpicto($text, $helptext, 1, 'help', '', 0, 2, 'idhelptext');
1380  print '</td>';
1381  if (empty($strictw3c)) print '<td align="center" width="80">'.$langs->trans("Action").'</td>';
1382  print "</tr>\n";
1383 
1384  $label='';
1385  $listofparam=array();
1386  foreach($tableau as $key => $const) // Loop on each param
1387  {
1388  $label='';
1389  // $const is a const key like 'MYMODULE_ABC'
1390  if (is_numeric($key)) { // Very old behaviour
1391  $type = 'string';
1392  }
1393  else
1394  {
1395  if (is_array($const))
1396  {
1397  $type = $const['type'];
1398  $label = $const['label'];
1399  $const = $key;
1400  }
1401  else
1402  {
1403  $type = $const;
1404  $const = $key;
1405  }
1406  }
1407 
1408  $sql = "SELECT ";
1409  $sql.= "rowid";
1410  $sql.= ", ".$db->decrypt('name')." as name";
1411  $sql.= ", ".$db->decrypt('value')." as value";
1412  $sql.= ", type";
1413  $sql.= ", note";
1414  $sql.= " FROM ".MAIN_DB_PREFIX."const";
1415  $sql.= " WHERE ".$db->decrypt('name')." = '".$db->escape($const)."'";
1416  $sql.= " AND entity IN (0, ".$conf->entity.")";
1417  $sql.= " ORDER BY name ASC, entity DESC";
1418  $result = $db->query($sql);
1419 
1420  dol_syslog("List params", LOG_DEBUG);
1421  if ($result)
1422  {
1423  $obj = $db->fetch_object($result); // Take first result of select
1424 
1425  if (empty($obj)) // If not yet into table
1426  {
1427  $obj = (object) array('rowid'=>'','name'=>$const,'value'=>'','type'=>$type,'note'=>'');
1428  }
1429 
1430  if (empty($strictw3c))
1431  {
1432  print "\n".'<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1433  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1434  }
1435 
1436  print '<tr class="oddeven">';
1437 
1438  // Show constant
1439  print '<td>';
1440  if (empty($strictw3c)) print '<input type="hidden" name="action" value="update">';
1441  print '<input type="hidden" name="rowid'.(empty($strictw3c)?'':'[]').'" value="'.$obj->rowid.'">';
1442  print '<input type="hidden" name="constname'.(empty($strictw3c)?'':'[]').'" value="'.$const.'">';
1443  print '<input type="hidden" name="constnote_'.$obj->name.'" value="'.nl2br(dol_escape_htmltag($obj->note)).'">';
1444  print '<input type="hidden" name="consttype_'.$obj->name.'" value="'.($obj->type?$obj->type:'string').'">';
1445 
1446  print ($label ? $label : $langs->trans('Desc'.$const));
1447 
1448  if ($const == 'ADHERENT_MAILMAN_URL')
1449  {
1450  print '. '.$langs->trans("Example").': <a href="#" id="exampleclick1">'.img_down().'</a><br>';
1451  //print 'http://lists.exampe.com/cgi-bin/mailman/admin/%LISTE%/members?adminpw=%MAILMAN_ADMINPW%&subscribees=%EMAIL%&send_welcome_msg_to_this_batch=1';
1452  print '<div id="example1" class="hidden">';
1453  print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/add?subscribees_upload=%EMAIL%&amp;adminpw=%MAILMAN_ADMINPW%&amp;subscribe_or_invite=0&amp;send_welcome_msg_to_this_batch=0&amp;notification_to_list_owner=0';
1454  print '</div>';
1455  }
1456  if ($const == 'ADHERENT_MAILMAN_UNSUB_URL')
1457  {
1458  print '. '.$langs->trans("Example").': <a href="#" id="exampleclick2">'.img_down().'</a><br>';
1459  print '<div id="example2" class="hidden">';
1460  print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?unsubscribees_upload=%EMAIL%&amp;adminpw=%MAILMAN_ADMINPW%&amp;send_unsub_ack_to_this_batch=0&amp;send_unsub_notifications_to_list_owner=0';
1461  print '</div>';
1462  //print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%';
1463  }
1464  if ($const == 'ADHERENT_MAILMAN_LISTS')
1465  {
1466  print '. '.$langs->trans("Example").': <a href="#" id="exampleclick3">'.img_down().'</a><br>';
1467  print '<div id="example3" class="hidden">';
1468  print 'mymailmanlist<br>';
1469  print 'mymailmanlist1,mymailmanlist2<br>';
1470  print 'TYPE:Type1:mymailmanlist1,TYPE:Type2:mymailmanlist2<br>';
1471  if ($conf->categorie->enabled) print 'CATEG:Categ1:mymailmanlist1,CATEG:Categ2:mymailmanlist2<br>';
1472  print '</div>';
1473  //print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%';
1474  }
1475 
1476  print "</td>\n";
1477 
1478  // Value
1479  if ($const == 'ADHERENT_CARD_TYPE' || $const == 'ADHERENT_ETIQUETTE_TYPE')
1480  {
1481  print '<td>';
1482  // List of possible labels (defined into $_Avery_Labels variable set into format_cards.lib.php)
1483  require_once DOL_DOCUMENT_ROOT.'/core/lib/format_cards.lib.php';
1484  $arrayoflabels=array();
1485  foreach(array_keys($_Avery_Labels) as $codecards)
1486  {
1487  $arrayoflabels[$codecards]=$_Avery_Labels[$codecards]['name'];
1488  }
1489  print $form->selectarray('constvalue'.(empty($strictw3c)?'':'[]'),$arrayoflabels,($obj->value?$obj->value:'CARD'),1,0,0);
1490  print '<input type="hidden" name="consttype" value="yesno">';
1491  print '<input type="hidden" name="constnote'.(empty($strictw3c)?'':'[]').'" value="'.nl2br(dol_escape_htmltag($obj->note)).'">';
1492  print '</td>';
1493  }
1494  else
1495  {
1496  print '<td>';
1497  print '<input type="hidden" name="consttype'.(empty($strictw3c)?'':'[]').'" value="'.($obj->type?$obj->type:'string').'">';
1498  print '<input type="hidden" name="constnote'.(empty($strictw3c)?'':'[]').'" value="'.nl2br(dol_escape_htmltag($obj->note)).'">';
1499  if ($obj->type == 'textarea' || in_array($const,array('ADHERENT_CARD_TEXT','ADHERENT_CARD_TEXT_RIGHT','ADHERENT_ETIQUETTE_TEXT')))
1500  {
1501  print '<textarea class="flat" name="constvalue'.(empty($strictw3c)?'':'[]').'" cols="50" rows="5" wrap="soft">'."\n";
1502  print $obj->value;
1503  print "</textarea>\n";
1504  }
1505  elseif ($obj->type == 'html')
1506  {
1507  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1508  $doleditor=new DolEditor('constvalue_'.$const.(empty($strictw3c)?'':'[]'),$obj->value,'',160,'dolibarr_notes','',false,false,$conf->fckeditor->enabled,ROWS_5,'90%');
1509  $doleditor->Create();
1510  }
1511  elseif ($obj->type == 'yesno')
1512  {
1513  print $form->selectyesno('constvalue'.(empty($strictw3c)?'':'[]'),$obj->value,1);
1514  }
1515  elseif (preg_match('/emailtemplate/', $obj->type))
1516  {
1517  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
1518  $formmail = new FormMail($db);
1519 
1520  $tmp=explode(':', $obj->type);
1521 
1522  $nboftemplates = $formmail->fetchAllEMailTemplate($tmp[1], $user, null, -1); // We set lang=null to get in priority record with no lang
1523  //$arraydefaultmessage = $formmail->getEMailTemplate($db, $tmp[1], $user, null, 0, 1, '');
1524  $arrayofmessagename=array();
1525  if (is_array($formmail->lines_model))
1526  {
1527  foreach($formmail->lines_model as $modelmail)
1528  {
1529  //var_dump($modelmail);
1530  $moreonlabel='';
1531  if (! empty($arrayofmessagename[$modelmail->label])) $moreonlabel=' <span class="opacitymedium">('.$langs->trans("SeveralLangugeVariatFound").')</span>';
1532  $arrayofmessagename[$modelmail->label]=$langs->trans(preg_replace('/\(|\)/','',$modelmail->label)).$moreonlabel;
1533  }
1534  }
1535  //var_dump($arraydefaultmessage);
1536  //var_dump($arrayofmessagename);
1537  print $form->selectarray('constvalue_'.$obj->name, $arrayofmessagename, $obj->value, 'None', 1, 0, '', 0, 0, 0, '', '', 1);
1538  }
1539  else // type = 'string' ou 'chaine'
1540  {
1541  print '<input type="text" class="flat" size="48" name="constvalue'.(empty($strictw3c)?'':'[]').'" value="'.dol_escape_htmltag($obj->value).'">';
1542  }
1543  print '</td>';
1544  }
1545  // Submit
1546  if (empty($strictw3c))
1547  {
1548  print '<td align="center">';
1549  print '<input type="submit" class="button" value="'.$langs->trans("Update").'" name="Button">';
1550  print "</td>";
1551  }
1552  print "</tr>\n";
1553  if (empty($strictw3c)) print "</form>\n";
1554  }
1555  }
1556  print '</table>';
1557 
1558  if (! empty($strictw3c) && $strictw3c == 1)
1559  {
1560  print '<div align="center"><input type="submit" class="button" value="'.$langs->trans("Update").'" name="update"></div>';
1561  print "</form>\n";
1562  }
1563 }
1564 
1565 
1573 {
1574  global $conf,$langs;
1575 
1576  $text=$langs->trans("OnlyFollowingModulesAreOpenedToExternalUsers");
1577  $listofmodules=explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL);
1578  $i=0;
1579  if (!empty($modules)) {
1580  foreach($modules as $module)
1581  {
1582  $moduleconst=$module->const_name;
1583  $modulename=strtolower($module->name);
1584  //print 'modulename='.$modulename;
1585 
1586  //if (empty($conf->global->$moduleconst)) continue;
1587  if (! in_array($modulename,$listofmodules)) continue;
1588  //var_dump($modulename.' - '.$langs->trans('Module'.$module->numero.'Name'));
1589 
1590  if ($i > 0) $text.=', ';
1591  else $text.=' ';
1592  $i++;
1593  $text .= $langs->trans('Module'.$module->numero.'Name');
1594  }
1595  }
1596  return $text;
1597 }
1598 
1599 
1609 function addDocumentModel($name, $type, $label='', $description='')
1610 {
1611  global $db, $conf;
1612 
1613  $db->begin();
1614 
1615  $sql = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity, libelle, description)";
1616  $sql.= " VALUES ('".$db->escape($name)."','".$type."',".$conf->entity.", ";
1617  $sql.= ($label?"'".$db->escape($label)."'":'null').", ";
1618  $sql.= (! empty($description)?"'".$db->escape($description)."'":"null");
1619  $sql.= ")";
1620 
1621  dol_syslog("admin.lib::addDocumentModel", LOG_DEBUG);
1622  $resql=$db->query($sql);
1623  if ($resql)
1624  {
1625  $db->commit();
1626  return 1;
1627  }
1628  else
1629  {
1630  dol_print_error($db);
1631  $db->rollback();
1632  return -1;
1633  }
1634 }
1635 
1643 function delDocumentModel($name, $type)
1644 {
1645  global $db, $conf;
1646 
1647  $db->begin();
1648 
1649  $sql = "DELETE FROM ".MAIN_DB_PREFIX."document_model";
1650  $sql.= " WHERE nom = '".$db->escape($name)."'";
1651  $sql.= " AND type = '".$type."'";
1652  $sql.= " AND entity = ".$conf->entity;
1653 
1654  dol_syslog("admin.lib::delDocumentModel", LOG_DEBUG);
1655  $resql=$db->query($sql);
1656  if ($resql)
1657  {
1658  $db->commit();
1659  return 1;
1660  }
1661  else
1662  {
1663  dol_print_error($db);
1664  $db->rollback();
1665  return -1;
1666  }
1667 }
1668 
1669 
1675 function phpinfo_array()
1676 {
1677  ob_start();
1678  phpinfo();
1679  $info_arr = array();
1680  $info_lines = explode("\n", strip_tags(ob_get_clean(), "<tr><td><h2>")); // end of ob_start()
1681  $cat = "General";
1682  foreach($info_lines as $line)
1683  {
1684  // new cat?
1685  preg_match("~<h2>(.*)</h2>~", $line, $title) ? $cat = $title[1] : null;
1686  if(preg_match("~<tr><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td></tr>~", $line, $val))
1687  {
1688  $info_arr[trim($cat)][trim($val[1])] = $val[2];
1689  }
1690  elseif(preg_match("~<tr><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td></tr>~", $line, $val))
1691  {
1692  $info_arr[trim($cat)][trim($val[1])] = array("local" => $val[2], "master" => $val[3]);
1693  }
1694  }
1695  return $info_arr;
1696 }
1697 
1704 {
1705  global $langs, $conf, $user;
1706 
1707  $h = 0;
1708  $head = array();
1709 
1710  $head[$h][0] = DOL_URL_ROOT."/admin/company.php";
1711  $head[$h][1] = $langs->trans("Company");
1712  $head[$h][2] = 'company';
1713  $h++;
1714 
1715  $head[$h][0] = DOL_URL_ROOT."/admin/accountant.php";
1716  $head[$h][1] = $langs->trans("Accountant");
1717  $head[$h][2] = 'accountant';
1718  $h++;
1719 
1720  complete_head_from_modules($conf,$langs,null,$head,$h,'company_admin','remove');
1721 
1722  return $head;
1723 }
1724 
1731 {
1732  global $langs, $conf, $user;
1733 
1734  $h = 0;
1735  $head = array();
1736 
1737  if (! empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates'))
1738  {
1739  $head[$h][0] = DOL_URL_ROOT."/admin/mails.php";
1740  $head[$h][1] = $langs->trans("OutGoingEmailSetup");
1741  $head[$h][2] = 'common';
1742  $h++;
1743 
1744  if ($conf->mailing->enabled)
1745  {
1746  $head[$h][0] = DOL_URL_ROOT."/admin/mails_emailing.php";
1747  $head[$h][1] = $langs->trans("OutGoingEmailSetupForEmailing");
1748  $head[$h][2] = 'common_emailing';
1749  $h++;
1750  }
1751  }
1752 
1753  $head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php";
1754  $head[$h][1] = $langs->trans("EMailTemplates");
1755  $head[$h][2] = 'templates';
1756  $h++;
1757 
1758  if ($conf->global->MAIN_FEATURES_LEVEL >= 1 && ! empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates'))
1759  {
1760  $head[$h][0] = DOL_URL_ROOT."/admin/mails_senderprofile_list.php";
1761  $head[$h][1] = $langs->trans("EmailSenderProfiles");
1762  $head[$h][2] = 'senderprofiles';
1763  $h++;
1764  }
1765 
1766  complete_head_from_modules($conf,$langs,null,$head,$h,'email_admin','remove');
1767 
1768  return $head;
1769 }
1770 
1771 
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
delDocumentModel($name, $type)
Delete document model used by doc generator.
Definition: admin.lib.php:1643
Classe permettant la generation du formulaire html d&#39;envoi de mail unitaire Usage: $formail = new For...
Class DolibarrModules.
print
Draft customers invoices.
Definition: index.php:91
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->lire) if(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) if(! empty($conf->facture->enabled) &&! empty($conf->commande->enabled) && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
dolibarr_get_const($db, $name, $entity=1)
Recupere une constante depuis la base de donnees.
Definition: admin.lib.php:475
unActivateModule($value, $requiredby=1)
Disable a module.
Definition: admin.lib.php:1011
complete_elementList_with_modules(&$elementList)
Add external modules to list of contact element.
Definition: admin.lib.php:1262
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add')
Complete or removed entries into a head array (used to build tabs).
listOfSessions()
Return list of session.
Definition: admin.lib.php:759
purgeSessions($mysessionid)
Purge existing sessions.
Definition: admin.lib.php:817
email_admin_prepare_head()
Return array head with list of tabs to view object informations.
Definition: admin.lib.php:1730
dolGetModulesDirs($subdir='')
Return list of modules directories.
versiondolibarrarray()
Return version Dolibarr.
Definition: admin.lib.php:104
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
Definition: admin.lib.php:510
showModulesExludedForExternal($modules)
Show array with constants to edit.
Definition: admin.lib.php:1572
addDocumentModel($name, $type, $label='', $description='')
Add document model used by doc generator.
Definition: admin.lib.php:1609
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
form_constantes($tableau, $strictw3c=0, $helptext='')
Show array with constants to edit.
Definition: admin.lib.php:1365
versiontostring($versionarray)
Renvoi une version en chaine depuis une version en tableau.
Definition: admin.lib.php:35
translation_prepare_head()
Prepare array with list of tabs.
Definition: admin.lib.php:676
img_down($titlealt='default', $selected=0, $moreclass='')
Show down arrow logo.
company_admin_prepare_head()
Return array head with list of tabs to view object informations.
Definition: admin.lib.php:1703
Class to manage generation of HTML components Only common components must be here.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
complete_dictionary_with_modules(&$taborder, &$tabname, &$tablib, &$tabsql, &$tabsqlsort, &$tabfield, &$tabfieldvalue, &$tabfieldinsert, &$tabrowid, &$tabcond, &$tabhelp, &$tabfieldcheck)
Add external modules to list of dictionaries.
Definition: admin.lib.php:1088
dolibarr_del_const($db, $name, $entity=1)
Effacement d&#39;une constante dans la base de donnees.
Definition: admin.lib.php:435
versioncompare($versionarray1, $versionarray2)
Compare 2 versions (stored into 2 arrays).
Definition: admin.lib.php:58
run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='', $okerror='default', $linelengthlimit=32768, $nocommentremoval=0, $offsetforchartofaccount=0)
Launch a sql file.
Definition: admin.lib.php:130
security_prepare_head()
Prepare array with list of tabs.
Definition: admin.lib.php:606
phpinfo_array()
Return the php_info into an array.
Definition: admin.lib.php:1675
activateModulesRequiredByCountry($country_code)
Activate external modules mandatory when country is country_code.
Definition: admin.lib.php:1198
defaultvalues_prepare_head()
Prepare array with list of tabs.
Definition: admin.lib.php:706
activateModule($value, $withdeps=1)
Enable a module.
Definition: admin.lib.php:867
Class to manage a WYSIWYG editor.
modules_prepare_head()
Prepare array with list of tabs.
Definition: admin.lib.php:571
dol_htmlentities($string, $flags=null, $encoding='UTF-8', $double_encode=false)
Replace htmlentities functions.
versionphparray()
Return version PHP.
Definition: admin.lib.php:94
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.