dolibarr  9.0.0
repair.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
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  */
20 
26 include_once 'inc.php';
27 if (file_exists($conffile)) include_once $conffile;
28 require_once $dolibarr_main_document_root.'/core/lib/admin.lib.php';
29 include_once $dolibarr_main_document_root.'/core/lib/images.lib.php';
30 require_once $dolibarr_main_document_root.'/core/class/extrafields.class.php';
31 require_once 'lib/repair.lib.php';
32 
33 $grant_query='';
34 $step = 2;
35 $ok = 0;
36 
37 
38 // Cette page peut etre longue. On augmente le delai autorise.
39 // Ne fonctionne que si on est pas en safe_mode.
40 $err=error_reporting();
41 error_reporting(0);
42 @set_time_limit(120);
43 error_reporting($err);
44 
45 $setuplang=GETPOST("selectlang",'az09',3)?GETPOST("selectlang",'az09',3):'auto';
46 $langs->setDefaultLang($setuplang);
47 
48 $langs->loadLangs(array("admin","install","other"));
49 
50 if ($dolibarr_main_db_type == "mysqli") $choix=1;
51 if ($dolibarr_main_db_type == "pgsql") $choix=2;
52 if ($dolibarr_main_db_type == "mssql") $choix=3;
53 
54 
55 dolibarr_install_syslog("--- repair: entering upgrade.php page");
56 if (! is_object($conf)) dolibarr_install_syslog("repair: conf file not initialized", LOG_ERR);
57 
58 
59 /*
60  * View
61  */
62 
63 pHeader('',"upgrade2",GETPOST('action','aZ09'));
64 
65 // Action to launch the repair script
66 $actiondone=1;
67 
68 print '<h3>'.$langs->trans("Repair").'</h3>';
69 
70 print 'Option standard (0 or \'confirmed\') is '.(GETPOST('standard','alpha')?GETPOST('standard','alpha'):'0').'<br>'."\n";
71 print 'Option restore_thirdparties_logos (0 or \'confirmed\') is '.(GETPOST('restore_thirdparties_logos','alpha')?GETPOST('restore_thirdparties_logos','alpha'):'0').'<br>'."\n";
72 print 'Option clean_linked_elements (0 or \'confirmed\') is '.(GETPOST('clean_linked_elements','alpha')?GETPOST('clean_linked_elements','alpha'):'0').'<br>'."\n";
73 print 'Option clean_menus (0 or \'test\' or \'confirmed\') is '.(GETPOST('clean_menus','alpha')?GETPOST('clean_menus','alpha'):'0').'<br>'."\n";
74 print 'Option clean_orphelin_dir (0 or \'test\' or \'confirmed\') is '.(GETPOST('clean_orphelin_dir','alpha')?GETPOST('clean_orphelin_dir','alpha'):'0').'<br>'."\n";
75 print 'Option clean_product_stock_batch (0 or \'test\' or \'confirmed\') is '.(GETPOST('clean_product_stock_batch','alpha')?GETPOST('clean_product_stock_batch','alpha'):'0').'<br>'."\n";
76 print 'Option set_empty_time_spent_amount (0 or \'test\' or \'confirmed\') is '.(GETPOST('set_empty_time_spent_amount','alpha')?GETPOST('set_empty_time_spent_amount','alpha'):'0').'<br>'."\n";
77 print 'Option rebuild_product_thumbs (0 or \'test\' or \'confirmed\') is '.(GETPOST('rebuild_product_thumbs','alpha')?GETPOST('rebuild_product_thumbs','alpha'):'0').'<br>'."\n";
78 print 'Option force_disable_of_modules_not_found (0 or \'test\' or \'confirmed\') is '.(GETPOST('force_disable_of_modules_not_found','alpha')?GETPOST('force_disable_of_modules_not_found','alpha'):'0').'<br>'."\n";
79 print 'Option clean_perm_table (0 or \'test\' or \'confirmed\') is '.(GETPOST('clean_perm_table','alpha')?GETPOST('clean_perm_table','alpha'):'0').'<br>'."\n";
80 print 'Option force_utf8_on_tables, for mysql/mariadb only (0 or \'test\' or \'confirmed\') is '.(GETPOST('force_utf8_on_tables','alpha')?GETPOST('force_utf8_on_tables','alpha'):'0').'<br>'."\n";
81 print '<br>';
82 
83 print '<table cellspacing="0" cellpadding="1" border="0" width="100%">';
84 $error=0;
85 
86 // If password is encoded, we decode it
87 if (preg_match('/crypted:/i',$dolibarr_main_db_pass) || ! empty($dolibarr_main_db_encrypted_pass))
88 {
89  require_once $dolibarr_main_document_root.'/core/lib/security.lib.php';
90  if (preg_match('/crypted:/i',$dolibarr_main_db_pass))
91  {
92  $dolibarr_main_db_pass = preg_replace('/crypted:/i', '', $dolibarr_main_db_pass);
93  $dolibarr_main_db_pass = dol_decode($dolibarr_main_db_pass);
94  $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass; // We need to set this as it is used to know the password was initially crypted
95  }
96  else $dolibarr_main_db_pass = dol_decode($dolibarr_main_db_encrypted_pass);
97 }
98 
99 // $conf is already instancied inside inc.php
100 $conf->db->type = $dolibarr_main_db_type;
101 $conf->db->host = $dolibarr_main_db_host;
102 $conf->db->port = $dolibarr_main_db_port;
103 $conf->db->name = $dolibarr_main_db_name;
104 $conf->db->user = $dolibarr_main_db_user;
105 $conf->db->pass = $dolibarr_main_db_pass;
106 
107 // For encryption
108 $conf->db->dolibarr_main_db_encryption = isset($dolibarr_main_db_encryption)?$dolibarr_main_db_encryption:'';
109 $conf->db->dolibarr_main_db_cryptkey = isset($dolibarr_main_db_cryptkey)?$dolibarr_main_db_cryptkey:'';
110 
111 $db=getDoliDBInstance($conf->db->type,$conf->db->host,$conf->db->user,$conf->db->pass,$conf->db->name,$conf->db->port);
112 
113 if ($db->connected)
114 {
115  print '<tr><td class="nowrap">';
116  print $langs->trans("ServerConnection")." : $dolibarr_main_db_host</td><td align=\"right\">".$langs->trans("OK")."</td></tr>";
117  dolibarr_install_syslog("repair: " . $langs->transnoentities("ServerConnection") . ": " . $dolibarr_main_db_host . $langs->transnoentities("OK"));
118  $ok = 1;
119 }
120 else
121 {
122  print "<tr><td>".$langs->trans("ErrorFailedToConnectToDatabase",$dolibarr_main_db_name)."</td><td align=\"right\">".$langs->transnoentities("Error")."</td></tr>";
123  dolibarr_install_syslog("repair: " . $langs->transnoentities("ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
124  $ok = 0;
125 }
126 
127 if ($ok)
128 {
129  if($db->database_selected)
130  {
131  print '<tr><td class="nowrap">';
132  print $langs->trans("DatabaseConnection")." : ".$dolibarr_main_db_name."</td><td align=\"right\">".$langs->trans("OK")."</td></tr>";
133  dolibarr_install_syslog("repair: database connection successful: " . $dolibarr_main_db_name);
134  $ok=1;
135  }
136  else
137  {
138  print "<tr><td>".$langs->trans("ErrorFailedToConnectToDatabase",$dolibarr_main_db_name)."</td><td align=\"right\">".$langs->trans("Error")."</td></tr>";
139  dolibarr_install_syslog("repair: " . $langs->transnoentities("ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
140  $ok=0;
141  }
142 }
143 
144 // Show database version
145 if ($ok)
146 {
147  $version=$db->getVersion();
148  $versionarray=$db->getVersionArray();
149  print '<tr><td>'.$langs->trans("ServerVersion").'</td>';
150  print '<td align="right">'.$version.'</td></tr>';
151  dolibarr_install_syslog("repair: " . $langs->transnoentities("ServerVersion") . ": " . $version);
152  //print '<td align="right">'.join('.',$versionarray).'</td></tr>';
153 }
154 
155 $conf->setValues($db);
156 // Reset forced setup after the setValues
157 if (defined('SYSLOG_FILE')) $conf->global->SYSLOG_FILE=constant('SYSLOG_FILE');
158 $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
159 
160 
161 /* Start action here */
162 $oneoptionset=0;
163 $oneoptionset=(GETPOST('standard', 'alpha') || GETPOST('restore_thirdparties_logos','alpha') || GETPOST('clean_linked_elements','alpha') || GETPOST('clean_menus','alpha')
164  || GETPOST('clean_orphelin_dir','alpha') || GETPOST('clean_product_stock_batch','alpha') || GETPOST('set_empty_time_spent_amount','alpha') || GETPOST('rebuild_product_thumbs','alpha')
165  || GETPOST('clean_perm_table','alpha')
166  || GETPOST('force_disable_of_modules_not_found','alpha') || GETPOST('force_utf8_on_tables','alpha'));
167 
168 if ($ok && $oneoptionset)
169 {
170  // Show wait message
171  print '<tr><td colspan="2">'.$langs->trans("PleaseBePatient").'<br><br></td></tr>';
172  flush();
173 }
174 
175 
176 // run_sql: Run repair SQL file
177 if ($ok && GETPOST('standard', 'alpha'))
178 {
179  $dir = "mysql/migration/";
180 
181  $filelist=array();
182  $i = 0;
183  $ok = 0;
184 
185  // Recupere list fichier
186  $filesindir=array();
187  $handle=opendir($dir);
188  if (is_resource($handle))
189  {
190  while (($file = readdir($handle))!==false)
191  {
192  if (preg_match('/\.sql$/i',$file)) $filesindir[]=$file;
193  }
194  }
195  sort($filesindir);
196 
197  foreach($filesindir as $file)
198  {
199  if (preg_match('/repair/i',$file))
200  {
201  $filelist[]=$file;
202  }
203  }
204 
205  // Loop on each file
206  foreach($filelist as $file)
207  {
208  print '<tr><td class="nowrap">*** ';
209  print $langs->trans("Script").'</td><td align="right">'.$file.'</td></tr>';
210 
211  $name = substr($file, 0, dol_strlen($file) - 4);
212 
213  // Run sql script
214  $ok=run_sql($dir.$file, 0, '', 1);
215  }
216 }
217 
218 
219 // sync_extrafields: Search list of fields declared and list of fields created into databases, then create fields missing
220 
221 if ($ok && GETPOST('standard', 'alpha'))
222 {
223  $extrafields=new ExtraFields($db);
224  $listofmodulesextra=array('societe'=>'societe','adherent'=>'adherent','product'=>'product',
225  'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture',
226  'supplier_proposal'=>'supplier_proposal', 'commande_fournisseur'=>'commande_fournisseur', 'facture_fourn'=>'facture_fourn',
227  'actioncomm'=>'actioncomm',
228  'adherent_type'=>'adherent_type','user'=>'user','projet'=>'projet', 'projet_task'=>'projet_task');
229  print '<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
230  foreach($listofmodulesextra as $tablename => $elementtype)
231  {
232  // Get list of fields
233  $tableextra=MAIN_DB_PREFIX.$tablename.'_extrafields';
234 
235  // Define $arrayoffieldsdesc
236  $arrayoffieldsdesc=$extrafields->fetch_name_optionals_label($elementtype);
237 
238  // Define $arrayoffieldsfound
239  $arrayoffieldsfound=array();
240  $resql=$db->DDLDescTable($tableextra);
241  if ($resql)
242  {
243  print '<tr><td>Check availability of extra field for '.$tableextra."<br>\n";
244  $i=0;
245  while($obj=$db->fetch_object($resql))
246  {
247  $fieldname=$fieldtype='';
248  if (preg_match('/mysql/',$db->type))
249  {
250  $fieldname=$obj->Field;
251  $fieldtype=$obj->Type;
252  }
253  else
254  {
255  $fieldname = isset($obj->Key)?$obj->Key:$obj->attname;
256  $fieldtype = isset($obj->Type)?$obj->Type:'varchar';
257  }
258 
259  if (empty($fieldname)) continue;
260  if (in_array($fieldname,array('rowid','tms','fk_object','import_key'))) continue;
261  $arrayoffieldsfound[$fieldname]=array('type'=>$fieldtype);
262  }
263 
264  // If it does not match, we create fields
265  foreach($arrayoffieldsdesc as $code => $label)
266  {
267  if (! in_array($code,array_keys($arrayoffieldsfound)))
268  {
269  print 'Found field '.$code.' declared into '.MAIN_DB_PREFIX.'extrafields table but not found into desc of table '.$tableextra." -> ";
270  $type=$extrafields->attributes[$elementtype]['type'][$code]; $length=$extrafields->attributes[$elementtype]['size'][$code]; $attribute=''; $default=''; $extra=''; $null='null';
271 
272  if ($type=='boolean') {
273  $typedb='int';
274  $lengthdb='1';
275  } elseif($type=='price') {
276  $typedb='double';
277  $lengthdb='24,8';
278  } elseif($type=='phone') {
279  $typedb='varchar';
280  $lengthdb='20';
281  }elseif($type=='mail') {
282  $typedb='varchar';
283  $lengthdb='128';
284  } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox') ||($type=='chkbxlst')){
285  $typedb='text';
286  $lengthdb='';
287  } elseif ($type=='link') {
288  $typedb='int';
289  $lengthdb='11';
290  } else {
291  $typedb=$type;
292  $lengthdb=$length;
293  }
294 
295  $field_desc=array(
296  'type'=>$typedb,
297  'value'=>$lengthdb,
298  'attribute'=>$attribute,
299  'default'=>$default,
300  'extra'=>$extra,
301  'null'=>$null
302  );
303  //var_dump($field_desc);exit;
304 
305  $result=$db->DDLAddField($tableextra,$code,$field_desc,"");
306  if ($result < 0)
307  {
308  print "KO ".$db->lasterror."<br>\n";
309  }
310  else
311  {
312  print "OK<br>\n";
313  }
314  }
315  }
316 
317  print "</td><td>&nbsp;</td></tr>\n";
318  }
319  else
320  {
321  dol_print_error($db);
322  }
323  }
324 }
325 
326 
327 
328 // clean_data_ecm_dir: Clean data into ecm_directories table
329 if ($ok && GETPOST('standard', 'alpha'))
330 {
332 }
333 
334 
335 
336 
337 /* From here, actions need a parameter */
338 
339 
340 
341 // restore_thirdparties_logos: Move logos to correct new directory.
342 if ($ok && GETPOST('restore_thirdparties_logos'))
343 {
344  //$exts=array('gif','png','jpg');
345 
346  $ext='';
347 
348  print '<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
349  //foreach($exts as $ext)
350  //{
351  $sql="SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX."societe as s ORDER BY s.nom";
352  $resql=$db->query($sql);
353  if ($resql)
354  {
355  $num=$db->num_rows($resql);
356  $i=0;
357 
358  while($i < $num)
359  {
360  $obj=$db->fetch_object($resql);
361 
362  /*
363  $name=preg_replace('/é/','',$obj->name);
364  $name=preg_replace('/ /','_',$name);
365  $name=preg_replace('/\'/','',$name);
366  */
367 
368  $tmp=explode('.',$obj->logo);
369  $name=$tmp[0];
370  if (isset($tmp[1])) $ext='.'.$tmp[1];
371 
372  if (! empty($name))
373  {
374  $filetotest=$dolibarr_main_data_root.'/societe/logos/'.$name.$ext;
375  $filetotestsmall=$dolibarr_main_data_root.'/societe/logos/thumbs/'.$name.$ext;
376  $exists=dol_is_file($filetotest);
377  print 'Check thirdparty '.$obj->rowid.' name='.$obj->name.' logo='.$obj->logo.' file '.$filetotest." exists=".$exists."<br>\n";
378  if ($exists)
379  {
380  $filetarget=$dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos/'.$name.$ext;
381  $filetargetsmall=$dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos/thumbs/'.$name.'_small'.$ext;
382  $existt=dol_is_file($filetarget);
383  if (! $existt)
384  {
385  dol_mkdir($dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos');
386 
387  print " &nbsp; &nbsp; &nbsp; -> Copy file ".$filetotest." -> ".$filetarget."<br>\n";
388  dol_copy($filetotest, $filetarget, '', 0);
389  }
390 
391  $existtt=dol_is_file($filetargetsmall);
392  if (! $existtt)
393  {
394  dol_mkdir($dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos/thumbs');
395 
396  print " &nbsp; &nbsp; &nbsp; -> Copy file ".$filetotestsmall." -> ".$filetargetsmall."<br>\n";
397  dol_copy($filetotestsmall, $filetargetsmall, '', 0);
398  }
399  }
400  }
401 
402  $i++;
403  }
404  }
405  else
406  {
407  $ok=0;
408  dol_print_error($db);
409  }
410 
411  print '</td></tr>';
412  //}
413 }
414 
415 
416 // rebuild_product_thumbs: Rebuild thumbs for product files
417 if ($ok && GETPOST('rebuild_product_thumbs','alpha'))
418 {
419  $ext='';
420  global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
421 
422  print '<tr><td colspan="2"><br>*** Rebuild product thumbs<br>';
423 
424  $sql="SELECT s.rowid, s.ref FROM ".MAIN_DB_PREFIX."product as s ORDER BY s.ref";
425  $resql=$db->query($sql);
426  if ($resql)
427  {
428  $num=$db->num_rows($resql);
429  $i=0;
430 
431  while($i < $num)
432  {
433  $obj=$db->fetch_object($resql);
434 
435  if (! empty($obj->ref))
436  {
437  $files=dol_dir_list($dolibarr_main_data_root.'/produit/'.$obj->ref, 'files', 0);
438  foreach($files as $file)
439  {
440  // Generate thumbs.
441  if (image_format_supported($file['fullname']) == 1)
442  {
443  $imgThumbSmall='notbuild';
444  if (GETPOST('rebuild_product_thumbs','alpha') == 'confirmed')
445  {
446  // Used on logon for example
447  $imgThumbSmall = vignette($file['fullname'], $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs");
448  }
449  print 'Check product '.$obj->rowid.", file ".$file['fullname']." -> ".$imgThumbSmall." maxwidthsmall=".$maxwidthsmall." maxheightsmall=".$maxheightsmall."<br>\n";
450  $imgThumbMini='notbuild';
451  if (GETPOST('rebuild_product_thumbs','alpha') == 'confirmed')
452  {
453  // Create mini thumbs for image (Ratio is near 16/9)
454  // Used on menu or for setup page for example
455  $imgThumbMini = vignette($file['fullname'], $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs");
456  }
457  print 'Check product '.$obj->rowid.", file ".$file['fullname']." -> ".$imgThumbMini." maxwidthmini=".$maxwidthmini." maxheightmini=".$maxheightmini."<br>\n";
458  }
459  }
460  }
461 
462  $i++;
463  }
464  }
465  else
466  {
467  $ok=0;
468  dol_print_error($db);
469  }
470 
471  print '</td></tr>';
472 }
473 
474 // clean_linked_elements: Check and clean linked elements
475 if ($ok && GETPOST('clean_linked_elements','alpha'))
476 {
477  print '<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
478  // propal => order
479  print '<tr><td colspan="2">'.checkLinkedElements('propal', 'commande')."</td></tr>\n";
480 
481  // propal => invoice
482  print '<tr><td colspan="2">'.checkLinkedElements('propal', 'facture')."</td></tr>\n";
483 
484  // order => invoice
485  print '<tr><td colspan="2">'.checkLinkedElements('commande', 'facture')."</td></tr>\n";
486 
487  // order => shipping
488  print '<tr><td colspan="2">'.checkLinkedElements('commande', 'shipping')."</td></tr>\n";
489 
490  // shipping => delivery
491  print '<tr><td colspan="2">'.checkLinkedElements('shipping', 'delivery')."</td></tr>\n";
492 
493  // order_supplier => invoice_supplier
494  print '<tr><td colspan="2">'.checkLinkedElements('order_supplier', 'invoice_supplier')."</td></tr>\n";
495 }
496 
497 
498 // clean_menus: Check orphelins menus
499 if ($ok && GETPOST('clean_menus','alpha'))
500 {
501  print '<tr><td colspan="2"><br>*** Clean menu entries coming from disabled modules</td></tr>';
502 
503  $sql ="SELECT rowid, module";
504  $sql.=" FROM ".MAIN_DB_PREFIX."menu as c";
505  $sql.=" WHERE module IS NOT NULL AND module <> ''";
506  $sql.=" ORDER BY module";
507 
508  $resql = $db->query($sql);
509  if ($resql)
510  {
511  $num = $db->num_rows($resql);
512  if ($num)
513  {
514  $i = 0;
515  while ($i < $num)
516  {
517  $obj=$db->fetch_object($resql);
518 
519  $modulecond=$obj->module;
520  $modulecondarray = explode('|',$obj->module); // Name of module
521 
522  print '<tr><td>';
523  print $modulecond;
524 
525  $db->begin();
526 
527  if ($modulecond) // And menu entry for module $modulecond was found in database.
528  {
529  $moduleok=0;
530  foreach($modulecondarray as $tmpname)
531  {
532  if ($tmpname == 'margins') $tmpname='margin'; // TODO Remove this when normalized
533 
534  $result = 0;
535  if (! empty($conf->$tmpname)) $result = $conf->$tmpname->enabled;
536  if ($result) $moduleok++;
537  }
538 
539  if (! $moduleok && $modulecond)
540  {
541  print ' - Module condition '.$modulecond.' seems ko, we delete menu entry.';
542  if (GETPOST('clean_menus') == 'confirmed')
543  {
544  $sql2 ="DELETE FROM ".MAIN_DB_PREFIX."menu WHERE module = '".$modulecond."'";
545  $resql2=$db->query($sql2);
546  if (! $resql2)
547  {
548  $error++;
549  dol_print_error($db);
550  }
551  else
552  print ' - <span class="warning">Cleaned</span>';
553  }
554  else
555  {
556  print ' - <span class="warning">Canceled (test mode)</span>';
557  }
558  }
559  else
560  {
561  print ' - Module condition '.$modulecond.' is ok, we do nothing.';
562  }
563  }
564 
565  if (!$error) $db->commit();
566  else $db->rollback();
567 
568  print'</td></tr>';
569 
570  if ($error) break;
571 
572  $i++;
573  }
574  }
575  else
576  {
577  print '<tr><td>No menu entries of disabled menus found</td></tr>';
578  }
579  }
580  else
581  {
582  dol_print_error($db);
583  }
584 }
585 
586 
587 
588 // clean_orphelin_dir: Run purge of directory
589 if ($ok && GETPOST('clean_orphelin_dir','alpha'))
590 {
591  $listmodulepart=array('company','invoice','invoice_supplier','propal','order','order_supplier','contract','tax');
592  foreach ($listmodulepart as $modulepart)
593  {
594  $filearray=array();
595  $upload_dir = isset($conf->$modulepart->dir_output)?$conf->$modulepart->dir_output:'';
596  if ($modulepart == 'company') $upload_dir = $conf->societe->dir_output; // TODO change for multicompany sharing
597  if ($modulepart == 'invoice') $upload_dir = $conf->facture->dir_output;
598  if ($modulepart == 'invoice_supplier') $upload_dir = $conf->fournisseur->facture->dir_output;
599  if ($modulepart == 'order') $upload_dir = $conf->commande->dir_output;
600  if ($modulepart == 'order_supplier') $upload_dir = $conf->fournisseur->commande->dir_output;
601  if ($modulepart == 'contract') $upload_dir = $conf->contrat->dir_output;
602 
603  if (empty($upload_dir)) continue;
604 
605  print '<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.'</td></tr>';
606 
607  $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','(\.meta|_preview.*\.png)$','^temp$','^payments$','^CVS$','^thumbs$'),'',SORT_DESC,1,true);
608 
609  // To show ref or specific information according to view to show (defined by $module)
610  if ($modulepart == 'company')
611  {
612  include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
613  $object_instance=new Societe($db);
614  }
615  if ($modulepart == 'invoice')
616  {
617  include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
618  $object_instance=new Facture($db);
619  }
620  else if ($modulepart == 'invoice_supplier')
621  {
622  include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
623  $object_instance=new FactureFournisseur($db);
624  }
625  else if ($modulepart == 'propal')
626  {
627  include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
628  $object_instance=new Propal($db);
629  }
630  else if ($modulepart == 'order')
631  {
632  include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
633  $object_instance=new Commande($db);
634  }
635  else if ($modulepart == 'order_supplier')
636  {
637  include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
638  $object_instance=new CommandeFournisseur($db);
639  }
640  else if ($modulepart == 'contract')
641  {
642  include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
643  $object_instance=new Contrat($db);
644  }
645  else if ($modulepart == 'tax')
646  {
647  include_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
648  $object_instance=new ChargeSociales($db);
649  }
650 
651  foreach($filearray as $key => $file)
652  {
653  if (!is_dir($file['name'])
654  && $file['name'] != '.'
655  && $file['name'] != '..'
656  && $file['name'] != 'CVS'
657  )
658  {
659  // Define relative path used to store the file
660  $relativefile=preg_replace('/'.preg_quote($upload_dir.'/','/').'/','',$file['fullname']);
661 
662  //var_dump($file);
663  $id=0; $ref=''; $object_instance->id=0; $object_instance->ref=''; $label='';
664 
665  // To show ref or specific information according to view to show (defined by $module)
666  if ($modulepart == 'invoice') {
667  preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=$reg[1];
668  }
669  if ($modulepart == 'invoice_supplier') {
670  preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=empty($reg[1])?'':$reg[1];
671  }
672  if ($modulepart == 'propal') {
673  preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=$reg[1];
674  }
675  if ($modulepart == 'order') {
676  preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=$reg[1];
677  }
678  if ($modulepart == 'order_supplier') {
679  preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=$reg[1];
680  }
681  if ($modulepart == 'contract') {
682  preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=$reg[1];
683  }
684  if ($modulepart == 'tax') {
685  preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=$reg[1];
686  }
687 
688  if ($id || $ref)
689  {
690  //print 'Fetch '.$id.' or '.$ref.'<br>';
691  $result=$object_instance->fetch($id,$ref);
692  //print $result.'<br>';
693  if ($result == 0) // Not found but no error
694  {
695  // Clean of orphelins directories are done into repair.php
696  print '<tr><td colspan="2">';
697  print 'Delete orphelins file '.$file['fullname'].'<br>';
698  if (GETPOST('clean_orphelin_dir','alpha') == 'confirmed')
699  {
700  dol_delete_file($file['fullname'],1,1,1);
701  dol_delete_dir(dirname($file['fullname']),1);
702  }
703  print "</td></tr>";
704  }
705  else if ($result < 0) print 'Error in '.get_class($object_instance).'.fetch of id'.$id.' ref='.$ref.', result='.$result.'<br>';
706  }
707  }
708  }
709  }
710 }
711 
712 // clean_linked_elements: Check and clean linked elements
713 if ($ok && GETPOST('clean_product_stock_batch','alpha'))
714 {
715  $methodtofix=GETPOST('methodtofix','alpha')?GETPOST('methodtofix','alpha'):'updatestock';
716 
717  print '<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.' (possible values: updatestock or updatebatch)</td></tr>';
718 
719  $sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
720  $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps LEFT JOIN ".MAIN_DB_PREFIX."product_batch as pb ON ps.rowid = pb.fk_product_stock";
721  $sql.=" WHERE p.rowid = ps.fk_product";
722  $sql.=" AND p.tobatch = 1";
723  $sql.=" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
724  $sql.=" HAVING reel != SUM(pb.qty) or SUM(pb.qty) IS NULL";
725  print $sql;
726  $resql = $db->query($sql);
727  if ($resql)
728  {
729  $num = $db->num_rows($resql);
730 
731  if ($num)
732  {
733  $i = 0;
734  while ($i < $num)
735  {
736  $obj=$db->fetch_object($resql);
737  print '<tr><td>Product '.$obj->rowid.'-'.$obj->ref.' in warehose '.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' (product_stock.reel) != '.($obj->reelbatch?$obj->reelbatch:'0').' (sum product_batch)';
738 
739  // Fix
740  if ($obj->reel != $obj->reelbatch)
741  {
742  if ($methodtofix == 'updatebatch')
743  {
744  // Method 1
745  print ' -> Insert qty '.($obj->reel - $obj->reelbatch).' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
746  if (GETPOST('clean_product_stock_batch') == 'confirmed')
747  {
748  $sql2 ="INSERT INTO ".MAIN_DB_PREFIX."product_batch(fk_product_stock, batch, qty)";
749  $sql2.="VALUES(".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
750  $resql2=$db->query($sql2);
751  if (! $resql2)
752  {
753  // TODO If it fails, we must make update
754  //$sql2 ="UPDATE ".MAIN_DB_PREFIX."product_batch";
755  //$sql2.=" SET ".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
756  //$sql2.=" WHERE fk_product_stock = ".$obj->psrowid"
757  }
758  }
759  }
760  if ($methodtofix == 'updatestock')
761  {
762  // Method 2
763  print ' -> Update qty of product_stock with qty = '.($obj->reelbatch?$obj->reelbatch:'0').' for ps.rowid = '.$obj->psrowid;
764  if (GETPOST('clean_product_stock_batch') == 'confirmed')
765  {
766  $error=0;
767 
768  $db->begin();
769 
770  $sql2 ="UPDATE ".MAIN_DB_PREFIX."product_stock";
771  $sql2.=" SET reel = ".($obj->reelbatch?$obj->reelbatch:'0')." WHERE rowid = ".$obj->psrowid;
772  $resql2=$db->query($sql2);
773  if ($resql2)
774  {
775  // We update product_stock, so we must field stock into product too.
776  $sql3='UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid)';
777  $resql3=$db->query($sql3);
778  if (! $resql3)
779  {
780  $error++;
781  dol_print_error($db);
782  }
783  }
784  else
785  {
786  $error++;
787  dol_print_error($db);
788  }
789 
790  if (!$error) $db->commit();
791  else $db->rollback();
792  }
793  }
794  }
795 
796  print'</td></tr>';
797 
798  $i++;
799  }
800  }
801  else
802  {
803  print '<tr><td colspan="2">Nothing to do</td></tr>';
804  }
805  }
806  else
807  {
808  dol_print_error($db);
809  }
810 }
811 
812 
813 // clean_product_stock_negative_if_batch
814 if ($ok && GETPOST('clean_product_stock_negative_if_batch','alpha'))
815 {
816  print '<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.' (possible values: updatestock or updatebatch)</td></tr>';
817 
818  $sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
819  $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb";
820  $sql.=" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
821  $sql.=" AND p.tobatch = 1";
822  $sql.=" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
823  $sql.=" HAVING reel != SUM(pb.qty)";
824  $resql = $db->query($sql);
825  if ($resql)
826  {
827  $num = $db->num_rows($resql);
828 
829  if ($num)
830  {
831  $i = 0;
832  while ($i < $num)
833  {
834  $obj=$db->fetch_object($resql);
835  print '<tr><td>'.$obj->rowid.'-'.$obj->ref.'-'.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' != '.$obj->reelbatch;
836 
837  // TODO
838  }
839  }
840  }
841 }
842 
843 // set_empty_time_spent_amount
844 if ($ok && GETPOST('set_empty_time_spent_amount','alpha'))
845 {
846  print '<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
847 
848  $sql ="SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
849  $sql.=" FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."user as u";
850  $sql.=" WHERE ptt.fk_user = u.rowid";
851  $sql.=" AND ptt.thm IS NULL and u.thm > 0";
852  $sql.=" GROUP BY u.rowid, u.login, u.thm";
853 
854  $resql = $db->query($sql);
855  if ($resql)
856  {
857  $num = $db->num_rows($resql);
858 
859  if ($num)
860  {
861  $i = 0;
862  while ($i < $num)
863  {
864  $obj=$db->fetch_object($resql);
865  print '<tr><td>'.$obj->login.'-'.$obj->user_id.' ('.$obj->nb.' lines to fix) -> '.$obj->user_thm;
866 
867  $db->begin();
868 
869  if (GETPOST('set_empty_time_spent_amount') == 'confirmed')
870  {
871  $sql2 ="UPDATE ".MAIN_DB_PREFIX."projet_task_time";
872  $sql2.=" SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".$obj->user_id;
873  $resql2=$db->query($sql2);
874  if (! $resql2)
875  {
876  $error++;
877  dol_print_error($db);
878  }
879  }
880 
881  if (!$error) $db->commit();
882  else $db->rollback();
883 
884  print'</td></tr>';
885 
886  if ($error) break;
887 
888  $i++;
889  }
890  }
891  else
892  {
893  print '<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
894  }
895  }
896  else
897  {
898  dol_print_error($db);
899  }
900 }
901 
902 
903 // force_disable_of_modules_not_found
904 if ($ok && GETPOST('force_disable_of_modules_not_found','alpha'))
905 {
906  print '<tr><td colspan="2"><br>*** Force modules not found to be disabled (only modules adding js, css or hooks can be detected as removed)</td></tr>';
907 
908  $arraylistofkey=array('hooks','js','css');
909 
910  foreach($arraylistofkey as $key)
911  {
912  $sql ="SELECT DISTINCT name, value";
913  $sql.=" FROM ".MAIN_DB_PREFIX."const as c";
914  $sql.=" WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($key)."'";
915  $sql.=" ORDER BY name";
916 
917  $resql = $db->query($sql);
918  if ($resql)
919  {
920  $num = $db->num_rows($resql);
921  if ($num)
922  {
923  $i = 0;
924  while ($i < $num)
925  {
926  $obj=$db->fetch_object($resql);
927  $constantname = $obj->name; // Name of constant for hook or js or css declaration
928 
929  print '<tr><td>';
930  print $constantname;
931 
932  $db->begin();
933 
934  if (preg_match('/MAIN_MODULE_(.*)_'.strtoupper($key).'/i', $constantname, $reg))
935  {
936  $name=strtolower($reg[1]);
937 
938  if ($name) // And entry for key $key and module $name was found in database.
939  {
940  if ($key == 'hooks') $reloffile=$name.'/class/actions_'.$name.'.class.php';
941  if ($key == 'js')
942  {
943  $value=$obj->value;
944  $valuearray=json_decode($value);
945  $reloffile=$valuearray[0];
946  $reloffile=preg_replace('/^\//','',$valuearray[0]);
947  }
948  if ($key == 'css')
949  {
950  $value=$obj->value;
951  $valuearray=json_decode($value);
952  if ($value && count($valuearray)==0) $valuearray[0]=$value; // If value was not a json array but a string
953  $reloffile=preg_replace('/^\//','',$valuearray[0]);
954  }
955 
956  //var_dump($key.' - '.$value.' - '.$reloffile);
957  try {
958  $result = dol_buildpath($reloffile, 0, 2);
959  }
960  catch(Exception $e)
961  {
962  // No catch yet
963  }
964 
965  if (! $result)
966  {
967  print ' - File of '.$key.' ('.$reloffile.') NOT found, we disable the module.';
968  if (GETPOST('force_disable_of_modules_not_found') == 'confirmed')
969  {
970  $sql2 ="DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = 'MAIN_MODULE_".strtoupper($name)."_".strtoupper($key)."'";
971  $resql2=$db->query($sql2);
972  if (! $resql2)
973  {
974  $error++;
975  dol_print_error($db);
976  }
977  $sql2 ="DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = 'MAIN_MODULE_".strtoupper($name)."'";
978  $resql2=$db->query($sql2);
979  if (! $resql2)
980  {
981  $error++;
982  dol_print_error($db);
983  }
984  else
985  print ' - <span class="warning">Cleaned</span>';
986  }
987  else
988  {
989  print ' - <span class="warning">Canceled (test mode)</span>';
990  }
991  }
992  else
993  {
994  print ' - File of '.$key.' ('.$reloffile.') found, we do nothing.';
995  }
996  }
997 
998  if (!$error) $db->commit();
999  else $db->rollback();
1000  }
1001 
1002  print'</td></tr>';
1003 
1004  if ($error) break;
1005 
1006  $i++;
1007  }
1008  }
1009  else
1010  {
1011  print '<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).'</td></tr>';
1012  }
1013  }
1014  else
1015  {
1016  dol_print_error($db);
1017  }
1018  }
1019 }
1020 
1021 
1022 // clean_old_module_entries: Clean data into const when files of module were removed without being
1023 if ($ok && GETPOST('clean_perm_table','alpha'))
1024 {
1025  print '<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1026 
1027  $listofmods='';
1028  foreach($conf->modules as $key => $val)
1029  {
1030  $listofmods.=($listofmods?',':'')."'".$val."'";
1031  }
1032  $sql = 'SELECT id, libelle, module from '.MAIN_DB_PREFIX.'rights_def WHERE module not in ('.$listofmods.') AND id > 100000';
1033  $resql = $db->query($sql);
1034  if ($resql)
1035  {
1036  $num = $db->num_rows($resql);
1037  if ($num)
1038  {
1039  $i = 0;
1040  while ($i < $num)
1041  {
1042  $obj=$db->fetch_object($resql);
1043  if ($obj->id > 0)
1044  {
1045  print '<tr><td>Found line with id '.$obj->id.', label "'.$obj->libelle.'" of module "'.$obj->module.'" to delete';
1046  if (GETPOST('clean_perm_table','alpha') == 'confirmed')
1047  {
1048  $sqldelete = 'DELETE FROM '.MAIN_DB_PREFIX.'rights_def WHERE id = '.$obj->id;
1049  $resqldelete = $db->query($sqldelete);
1050  if (! $resqldelete)
1051  {
1052  dol_print_error($db);
1053  }
1054  print ' - deleted';
1055  }
1056  print '</td></tr>';
1057  }
1058  $i++;
1059  }
1060  }
1061  else
1062  {
1063  print '<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1064  }
1065  }
1066  else
1067  {
1068  dol_print_error($db);
1069  }
1070 }
1071 
1072 
1073 
1074 // force utf8 on tables
1075 if ($ok && GETPOST('force_utf8_on_tables','alpha'))
1076 {
1077  print '<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8/utf8_unicode_ci (for mysql/mariadb only)</td></tr>';
1078 
1079  if ($db->type == "mysql" || $db->type == "mysqli")
1080  {
1081  $force_utf8_on_tables = GETPOST('force_utf8_on_tables','alpha');
1082 
1083  $listoftables = $db->DDLListTables($db->database_name);
1084 
1085  // Disable foreign key checking for avoid errors
1086  if ($force_utf8_on_tables == 'confirmed')
1087  {
1088  $sql='SET FOREIGN_KEY_CHECKS=0';
1089  print '<!-- '.$sql.' -->';
1090  $resql = $db->query($sql);
1091  }
1092 
1093  foreach($listoftables as $table)
1094  {
1095  // do not convert llx_const if mysql encrypt/decrypt is used
1096  if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match('/\_const$/', $table)) continue;
1097 
1098  print '<tr><td colspan="2">';
1099  print $table;
1100  $sql='ALTER TABLE '.$table.' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci';
1101  print '<!-- '.$sql.' -->';
1102  if ($force_utf8_on_tables == 'confirmed')
1103  {
1104  $resql = $db->query($sql);
1105  print ' - Done ('.($resql?'OK':'KO').')';
1106  }
1107  else print ' - Disabled';
1108  print '</td></tr>';
1109  }
1110 
1111  // Enable foreign key checking
1112  if ($force_utf8_on_tables == 'confirmed')
1113  {
1114  $sql='SET FOREIGN_KEY_CHECKS=1';
1115  print '<!-- '.$sql.' -->';
1116  $resql = $db->query($sql);
1117  }
1118  }
1119  else
1120  {
1121  print '<tr><td colspan="2">Not available with database type '.$db->type.'</td></tr>';
1122  }
1123 }
1124 
1125 
1126 print '</table>';
1127 
1128 
1129 
1130 if (empty($actiondone))
1131 {
1132  print '<div class="error">'.$langs->trans("ErrorWrongParameters").'</div>';
1133 }
1134 
1135 if ($oneoptionset)
1136 {
1137  print '<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(isset($_POST["login"])?'&username='.urlencode($_POST["login"]):'').'">';
1138  print $langs->trans("GoToDolibarr");
1139  print '</a></div>';
1140 }
1141 else
1142 {
1143  print '<div class="center warning" style="padding-top: 10px">';
1144  print $langs->trans("SetAtLeastOneOptionAsUrlParameter");
1145  print '</div>';
1146 }
1147 
1148 dolibarr_install_syslog("--- repair: end");
1149 pFooter(1,$setuplang);
1150 
1151 if ($db->connected) $db->close();
1152 
1153 // Return code if ran from command line
1154 if (! $ok && isset($argv[1])) exit(1);
image_format_supported($file)
Return if a filename is file name of a supported image format.
Definition: images.lib.php:38
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
Copy a file to another file.
Definition: files.lib.php:666
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
getDoliDBInstance($type, $host, $user, $pass, $name, $port)
Return a DoliDB instance (database handler).
print
Draft customers invoices.
Definition: index.php:91
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
clean_data_ecm_directories()
Clean data into ecm_directories table.
Definition: repair.lib.php:118
Class to manage contracts.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
Class to manage suppliers invoices.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dolibarr_install_syslog($message, $level=LOG_DEBUG)
Log function for install pages.
Definition: inc.php:511
pHeader($subtitle, $next, $action='set', $param='', $forcejqueryurl='', $csstable='main-inside')
Show HTML header of install pages.
Definition: inc.php:377
Class to manage standard extra fields.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage customers orders.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1)
Remove a file or several files with a mask.
Definition: files.lib.php:1139
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
if(GETPOST('cancel', 'alpha')) if(! GETPOST( 'confirmmassaction', 'alpha') &&$massaction !='presend' &&$massaction !='confirm_presend')
Draft customers invoices.
Definition: list.php:156
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:59
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.
Class to manage predefined suppliers products.
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:451
pFooter($nonext=0, $setuplang='', $jscheckfunction='', $withpleasewait=0)
Print HTML footer of install pages.
Definition: inc.php:454
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
Class to manage invoices.
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
Definition: files.lib.php:1249
Classe permettant la gestion des paiements des charges La tva collectee n&#39;est calculee que sur les fa...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Class to manage proposals.
vignette($file, $maxWidth=160, $maxHeight=120, $extName='_small', $quality=50, $outdir='thumbs', $targetformat=0)
Create a thumbnail from an image file (Supported extensions are gif, jpg, png and bmp)...
Definition: images.lib.php:352