dolibarr  17.0.4
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  * Copyright (C) 2021 Frédéric France <frederic.france@free.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
27 include_once 'inc.php';
28 if (file_exists($conffile)) {
29  include_once $conffile;
30 }
31 require_once $dolibarr_main_document_root.'/core/lib/admin.lib.php';
32 include_once $dolibarr_main_document_root.'/core/lib/images.lib.php';
33 require_once $dolibarr_main_document_root.'/core/class/extrafields.class.php';
34 require_once 'lib/repair.lib.php';
35 
36 $step = 2;
37 $ok = 0;
38 
39 
40 // Cette page peut etre longue. On augmente le delai autorise.
41 // Ne fonctionne que si on est pas en safe_mode.
42 $err = error_reporting();
43 error_reporting(0);
44 @set_time_limit(120);
45 error_reporting($err);
46 
47 $setuplang = GETPOST("selectlang", 'aZ09', 3) ?GETPOST("selectlang", 'aZ09', 3) : 'auto';
48 $langs->setDefaultLang($setuplang);
49 
50 $langs->loadLangs(array("admin", "install", "other"));
51 
52 if ($dolibarr_main_db_type == "mysqli") {
53  $choix = 1;
54 }
55 if ($dolibarr_main_db_type == "pgsql") {
56  $choix = 2;
57 }
58 if ($dolibarr_main_db_type == "mssql") {
59  $choix = 3;
60 }
61 
62 
63 dolibarr_install_syslog("--- repair: entering upgrade.php page");
64 if (!is_object($conf)) {
65  dolibarr_install_syslog("repair: conf file not initialized", LOG_ERR);
66 }
67 
68 
69 /*
70  * View
71  */
72 
73 pHeader('', "upgrade2", GETPOST('action', 'aZ09'));
74 
75 // Action to launch the repair script
76 $actiondone = 1;
77 
78 print '<h3>'.$langs->trans("Repair").'</h3>';
79 
80 print 'Option standard (\'test\' or \'confirmed\') is '.(GETPOST('standard', 'alpha') ?GETPOST('standard', 'alpha') : 'undefined').'<br>'."\n";
81 // Disable modules
82 print 'Option force_disable_of_modules_not_found (\'test\' or \'confirmed\') is '.(GETPOST('force_disable_of_modules_not_found', 'alpha') ?GETPOST('force_disable_of_modules_not_found', 'alpha') : 'undefined').'<br>'."\n";
83 // Files
84 print 'Option restore_thirdparties_logos (\'test\' or \'confirmed\') is '.(GETPOST('restore_thirdparties_logos', 'alpha') ?GETPOST('restore_thirdparties_logos', 'alpha') : 'undefined').'<br>'."\n";
85 print 'Option restore_user_pictures (\'test\' or \'confirmed\') is '.(GETPOST('restore_user_pictures', 'alpha') ?GETPOST('restore_user_pictures', 'alpha') : 'undefined').'<br>'."\n";
86 print 'Option rebuild_product_thumbs (\'test\' or \'confirmed\') is '.(GETPOST('rebuild_product_thumbs', 'alpha') ?GETPOST('rebuild_product_thumbs', 'alpha') : 'undefined').'<br>'."\n";
87 // Clean tables and data
88 print 'Option clean_linked_elements (\'test\' or \'confirmed\') is '.(GETPOST('clean_linked_elements', 'alpha') ?GETPOST('clean_linked_elements', 'alpha') : 'undefined').'<br>'."\n";
89 print 'Option clean_menus (\'test\' or \'confirmed\') is '.(GETPOST('clean_menus', 'alpha') ?GETPOST('clean_menus', 'alpha') : 'undefined').'<br>'."\n";
90 print 'Option clean_orphelin_dir (\'test\' or \'confirmed\') is '.(GETPOST('clean_orphelin_dir', 'alpha') ?GETPOST('clean_orphelin_dir', 'alpha') : 'undefined').'<br>'."\n";
91 print 'Option clean_product_stock_batch (\'test\' or \'confirmed\') is '.(GETPOST('clean_product_stock_batch', 'alpha') ?GETPOST('clean_product_stock_batch', 'alpha') : 'undefined').'<br>'."\n";
92 print 'Option clean_perm_table (\'test\' or \'confirmed\') is '.(GETPOST('clean_perm_table', 'alpha') ?GETPOST('clean_perm_table', 'alpha') : 'undefined').'<br>'."\n";
93 print 'Option repair_link_dispatch_lines_supplier_order_lines, (\'test\' or \'confirmed\') is '.(GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha') ?GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha') : 'undefined').'<br>'."\n";
94 // Init data
95 print 'Option set_empty_time_spent_amount (\'test\' or \'confirmed\') is '.(GETPOST('set_empty_time_spent_amount', 'alpha') ?GETPOST('set_empty_time_spent_amount', 'alpha') : 'undefined').'<br>'."\n";
96 // Structure
97 print 'Option force_utf8_on_tables (force utf8 + row=dynamic), for mysql/mariadb only (\'test\' or \'confirmed\') is '.(GETPOST('force_utf8_on_tables', 'alpha') ?GETPOST('force_utf8_on_tables', 'alpha') : 'undefined').'<br>'."\n";
98 print "Option force_utf8mb4_on_tables (force utf8mb4 + row=dynamic, EXPERIMENTAL!), for mysql/mariadb only ('test' or 'confirmed') is ".(GETPOST('force_utf8mb4_on_tables', 'alpha') ? GETPOST('force_utf8mb4_on_tables', 'alpha') : 'undefined')."<br>\n";
99 // Rebuild sequence
100 print 'Option rebuild_sequences, for postgresql only (\'test\' or \'confirmed\') is '.(GETPOST('rebuild_sequences', 'alpha') ?GETPOST('rebuild_sequences', 'alpha') : 'undefined').'<br>'."\n";
101 print '<br>';
102 
103 print '<table cellspacing="0" cellpadding="1" border="0" width="100%">';
104 $error = 0;
105 
106 // If password is encoded, we decode it
107 if (preg_match('/crypted:/i', $dolibarr_main_db_pass) || !empty($dolibarr_main_db_encrypted_pass)) {
108  require_once $dolibarr_main_document_root.'/core/lib/security.lib.php';
109  if (preg_match('/crypted:/i', $dolibarr_main_db_pass)) {
110  $dolibarr_main_db_pass = preg_replace('/crypted:/i', '', $dolibarr_main_db_pass);
111  $dolibarr_main_db_pass = dol_decode($dolibarr_main_db_pass);
112  $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
113  } else {
114  $dolibarr_main_db_pass = dol_decode($dolibarr_main_db_encrypted_pass);
115  }
116 }
117 
118 // $conf is already instancied inside inc.php
119 $conf->db->type = $dolibarr_main_db_type;
120 $conf->db->host = $dolibarr_main_db_host;
121 $conf->db->port = $dolibarr_main_db_port;
122 $conf->db->name = $dolibarr_main_db_name;
123 $conf->db->user = $dolibarr_main_db_user;
124 $conf->db->pass = $dolibarr_main_db_pass;
125 
126 // For encryption
127 $conf->db->dolibarr_main_db_encryption = isset($dolibarr_main_db_encryption) ? $dolibarr_main_db_encryption : '';
128 $conf->db->dolibarr_main_db_cryptkey = isset($dolibarr_main_db_cryptkey) ? $dolibarr_main_db_cryptkey : '';
129 
130 $db = getDoliDBInstance($conf->db->type, $conf->db->host, $conf->db->user, $conf->db->pass, $conf->db->name, $conf->db->port);
131 
132 if ($db->connected) {
133  print '<tr><td class="nowrap">';
134  print $langs->trans("ServerConnection")." : $dolibarr_main_db_host</td><td class=\"right\">".$langs->trans("OK")."</td></tr>";
135  dolibarr_install_syslog("repair: ".$langs->transnoentities("ServerConnection").": ".$dolibarr_main_db_host.$langs->transnoentities("OK"));
136  $ok = 1;
137 } else {
138  print "<tr><td>".$langs->trans("ErrorFailedToConnectToDatabase", $dolibarr_main_db_name)."</td><td class=\"right\">".$langs->transnoentities("Error")."</td></tr>";
139  dolibarr_install_syslog("repair: ".$langs->transnoentities("ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
140  $ok = 0;
141 }
142 
143 if ($ok) {
144  if ($db->database_selected) {
145  print '<tr><td class="nowrap">';
146  print $langs->trans("DatabaseConnection")." : ".$dolibarr_main_db_name."</td><td class=\"right\">".$langs->trans("OK")."</td></tr>";
147  dolibarr_install_syslog("repair: database connection successful: ".$dolibarr_main_db_name);
148  $ok = 1;
149  } else {
150  print "<tr><td>".$langs->trans("ErrorFailedToConnectToDatabase", $dolibarr_main_db_name)."</td><td class=\"right\">".$langs->trans("Error")."</td></tr>";
151  dolibarr_install_syslog("repair: ".$langs->transnoentities("ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
152  $ok = 0;
153  }
154 }
155 
156 // Show database version
157 if ($ok) {
158  $version = $db->getVersion();
159  $versionarray = $db->getVersionArray();
160  print '<tr><td>'.$langs->trans("ServerVersion").'</td>';
161  print '<td class="right">'.$version.'</td></tr>';
162  dolibarr_install_syslog("repair: ".$langs->transnoentities("ServerVersion").": ".$version);
163  //print '<td class="right">'.join('.',$versionarray).'</td></tr>';
164 }
165 
166 $conf->setValues($db);
167 // Reset forced setup after the setValues
168 if (defined('SYSLOG_FILE')) {
169  $conf->global->SYSLOG_FILE = constant('SYSLOG_FILE');
170 }
171 $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
172 
173 
174 /* Start action here */
175 $oneoptionset = 0;
176 $oneoptionset = (GETPOST('standard', 'alpha') || GETPOST('restore_thirdparties_logos', 'alpha') || GETPOST('clean_linked_elements', 'alpha') || GETPOST('clean_menus', 'alpha')
177  || GETPOST('clean_orphelin_dir', 'alpha') || GETPOST('clean_product_stock_batch', 'alpha') || GETPOST('set_empty_time_spent_amount', 'alpha') || GETPOST('rebuild_product_thumbs', 'alpha')
178  || GETPOST('clean_perm_table', 'alpha')
179  || GETPOST('force_disable_of_modules_not_found', 'alpha')
180  || GETPOST('force_utf8_on_tables', 'alpha') || GETPOST('force_utf8mb4_on_tables', 'alpha')
181  || GETPOST('rebuild_sequences', 'alpha'));
182 
183 if ($ok && $oneoptionset) {
184  // Show wait message
185  print '<tr><td colspan="2">'.$langs->trans("PleaseBePatient").'<br><br></td></tr>';
186  flush();
187 }
188 
189 
190 // run_sql: Run repair SQL file
191 if ($ok && GETPOST('standard', 'alpha')) {
192  $dir = "mysql/migration/";
193 
194  $filelist = array();
195  $i = 0;
196  $ok = 0;
197 
198  // Recupere list fichier
199  $filesindir = array();
200  $handle = opendir($dir);
201  if (is_resource($handle)) {
202  while (($file = readdir($handle)) !== false) {
203  if (preg_match('/\.sql$/i', $file)) {
204  $filesindir[] = $file;
205  }
206  }
207  }
208  sort($filesindir);
209 
210  foreach ($filesindir as $file) {
211  if (preg_match('/repair/i', $file)) {
212  $filelist[] = $file;
213  }
214  }
215 
216  // Loop on each file
217  foreach ($filelist as $file) {
218  print '<tr><td class="nowrap">*** ';
219  print $langs->trans("Script").'</td><td class="right">'.$file.'</td></tr>';
220 
221  $name = substr($file, 0, dol_strlen($file) - 4);
222 
223  // Run sql script
224  $ok = run_sql($dir.$file, 0, '', 1);
225  }
226 }
227 
228 
229 // sync_extrafields: Search list of fields declared and list of fields created into databases, then create fields missing
230 
231 if ($ok && GETPOST('standard', 'alpha')) {
232  $extrafields = new ExtraFields($db);
233  $listofmodulesextra = array('societe'=>'societe', 'adherent'=>'adherent', 'product'=>'product',
234  'socpeople'=>'socpeople', 'propal'=>'propal', 'commande'=>'commande', 'facture'=>'facture',
235  'supplier_proposal'=>'supplier_proposal', 'commande_fournisseur'=>'commande_fournisseur', 'facture_fourn'=>'facture_fourn',
236  'actioncomm'=>'actioncomm', 'bom_bom'=>'bom_bom', 'mrp_mo'=>'mrp_mo',
237  'adherent_type'=>'adherent_type', 'user'=>'user', 'projet'=>'projet', 'projet_task'=>'projet_task');
238  print '<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
239  foreach ($listofmodulesextra as $tablename => $elementtype) {
240  // Get list of fields
241  $tableextra = MAIN_DB_PREFIX.$tablename.'_extrafields';
242 
243  // Define $arrayoffieldsdesc
244  $arrayoffieldsdesc = $extrafields->fetch_name_optionals_label($elementtype);
245 
246  // Define $arrayoffieldsfound
247  $arrayoffieldsfound = array();
248  $resql = $db->DDLDescTable($tableextra);
249  if ($resql) {
250  print '<tr><td>Check availability of extra field for '.$tableextra."<br>\n";
251  $i = 0;
252  while ($obj = $db->fetch_object($resql)) {
253  $fieldname = $fieldtype = '';
254  if (preg_match('/mysql/', $db->type)) {
255  $fieldname = $obj->Field;
256  $fieldtype = $obj->Type;
257  } else {
258  $fieldname = isset($obj->Key) ? $obj->Key : $obj->attname;
259  $fieldtype = isset($obj->Type) ? $obj->Type : 'varchar';
260  }
261 
262  if (empty($fieldname)) {
263  continue;
264  }
265  if (in_array($fieldname, array('rowid', 'tms', 'fk_object', 'import_key'))) {
266  continue;
267  }
268  $arrayoffieldsfound[$fieldname] = array('type'=>$fieldtype);
269  }
270 
271  // If it does not match, we create fields
272  foreach ($arrayoffieldsdesc as $code => $label) {
273  if (!in_array($code, array_keys($arrayoffieldsfound))) {
274  print 'Found field '.$code.' declared into '.MAIN_DB_PREFIX.'extrafields table but not found into desc of table '.$tableextra." -> ";
275  $type = $extrafields->attributes[$elementtype]['type'][$code]; $length = $extrafields->attributes[$elementtype]['size'][$code]; $attribute = ''; $default = ''; $extra = ''; $null = 'null';
276 
277  if ($type == 'boolean') {
278  $typedb = 'int';
279  $lengthdb = '1';
280  } elseif ($type == 'price') {
281  $typedb = 'double';
282  $lengthdb = '24,8';
283  } elseif ($type == 'phone') {
284  $typedb = 'varchar';
285  $lengthdb = '20';
286  } elseif ($type == 'mail') {
287  $typedb = 'varchar';
288  $lengthdb = '128';
289  } elseif (($type == 'select') || ($type == 'sellist') || ($type == 'radio') || ($type == 'checkbox') || ($type == 'chkbxlst')) {
290  $typedb = 'text';
291  $lengthdb = '';
292  } elseif ($type == 'link') {
293  $typedb = 'int';
294  $lengthdb = '11';
295  } else {
296  $typedb = $type;
297  $lengthdb = $length;
298  }
299 
300  $field_desc = array(
301  'type'=>$typedb,
302  'value'=>$lengthdb,
303  'attribute'=>$attribute,
304  'default'=>$default,
305  'extra'=>$extra,
306  'null'=>$null
307  );
308  //var_dump($field_desc);exit;
309 
310  $result = 0;
311  if (GETPOST('standard', 'alpha') == 'confirmed') {
312  $result = $db->DDLAddField($tableextra, $code, $field_desc, "");
313 
314  if ($result < 0) {
315  print "KO ".$db->lasterror."<br>\n";
316  } else {
317  print "OK<br>\n";
318  }
319  } else {
320  print ' - Mode test, no column added.';
321  }
322  }
323  }
324 
325  print "</td><td>&nbsp;</td></tr>\n";
326  } else {
327  dol_print_error($db);
328  }
329  }
330 }
331 
332 
333 // clean_data_ecm_dir: Clean data into ecm_directories table
334 if ($ok && GETPOST('standard', 'alpha')) {
336 }
337 
338 
339 // clean declaration constants
340 if ($ok && GETPOST('standard', 'alpha')) {
341  print '<tr><td colspan="2"><br>*** Clean constant record of modules not enabled</td></tr>';
342 
343  $sql = "SELECT name, entity, value";
344  $sql .= " FROM ".MAIN_DB_PREFIX."const as c";
345  $sql .= " WHERE name LIKE 'MAIN_MODULE_%_TPL' OR name LIKE 'MAIN_MODULE_%_CSS' OR name LIKE 'MAIN_MODULE_%_JS' OR name LIKE 'MAIN_MODULE_%_HOOKS'";
346  $sql .= " OR name LIKE 'MAIN_MODULE_%_TRIGGERS' OR name LIKE 'MAIN_MODULE_%_THEME' OR name LIKE 'MAIN_MODULE_%_SUBSTITUTIONS' OR name LIKE 'MAIN_MODULE_%_MODELS'";
347  $sql .= " OR name LIKE 'MAIN_MODULE_%_MENUS' OR name LIKE 'MAIN_MODULE_%_LOGIN' OR name LIKE 'MAIN_MODULE_%_BARCODE' OR name LIKE 'MAIN_MODULE_%_TABS_%'";
348  $sql .= " OR name LIKE 'MAIN_MODULE_%_MODULEFOREXTERNAL'";
349  $sql .= " ORDER BY name, entity";
350 
351  $resql = $db->query($sql);
352  if ($resql) {
353  $num = $db->num_rows($resql);
354 
355  if ($num) {
356  $db->begin();
357 
358  $i = 0;
359  while ($i < $num) {
360  $obj = $db->fetch_object($resql);
361 
362  $reg = array();
363  if (preg_match('/MAIN_MODULE_([^_]+)_(.+)/i', $obj->name, $reg)) {
364  $name = $reg[1];
365  $type = $reg[2];
366 
367  $sql2 = "SELECT COUNT(*) as nb";
368  $sql2 .= " FROM ".MAIN_DB_PREFIX."const as c";
369  $sql2 .= " WHERE name = 'MAIN_MODULE_".$name."'";
370  $sql2 .= " AND entity = ".((int) $obj->entity);
371  $resql2 = $db->query($sql2);
372  if ($resql2) {
373  $obj2 = $db->fetch_object($resql2);
374  if ($obj2 && $obj2->nb == 0) {
375  // Module not found, so we can remove entry
376  $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = '".$db->escape($obj->name)."' AND entity = ".((int) $obj->entity);
377 
378  if (GETPOST('standard', 'alpha') == 'confirmed') {
379  $db->query($sqldelete);
380 
381  print '<tr><td>Widget '.$obj->name.' set in entity '.$obj->entity.' with value '.$obj->value.' -> Module '.$name.' not enabled in entity '.((int) $obj->entity).', we delete record</td></tr>';
382  } else {
383  print '<tr><td>Widget '.$obj->name.' set in entity '.$obj->entity.' with value '.$obj->value.' -> Module '.$name.' not enabled in entity '.((int) $obj->entity).', we should delete record (not done, mode test)</td></tr>';
384  }
385  } else {
386  //print '<tr><td>Constant '.$obj->name.' set in entity '.$obj->entity.' with value '.$obj->value.' -> Module found in entity '.$obj->entity.', we keep record</td></tr>';
387  }
388  }
389  }
390 
391  $i++;
392  }
393 
394  $db->commit();
395  }
396  } else {
397  dol_print_error($db);
398  }
399 }
400 
401 
402 // clean box of not enabled modules
403 if ($ok && GETPOST('standard', 'alpha')) {
404  print '<tr><td colspan="2"><br>*** Clean definition of boxes of modules not enabled</td></tr>';
405 
406  $sql = "SELECT file, entity FROM ".MAIN_DB_PREFIX."boxes_def";
407  $sql .= " WHERE file like '%@%'";
408 
409  $resql = $db->query($sql);
410  if ($resql) {
411  $num = $db->num_rows($resql);
412 
413  if ($num) {
414  $db->begin();
415 
416  $i = 0;
417  while ($i < $num) {
418  $obj = $db->fetch_object($resql);
419 
420  $reg = array();
421  if (preg_match('/^(.+)@(.+)$/i', $obj->file, $reg)) {
422  $name = $reg[1];
423  $module = $reg[2];
424 
425  $sql2 = "SELECT COUNT(*) as nb";
426  $sql2 .= " FROM ".MAIN_DB_PREFIX."const as c";
427  $sql2 .= " WHERE name = 'MAIN_MODULE_".strtoupper($module)."'";
428  $sql2 .= " AND entity = ".((int) $obj->entity);
429  $sql2 .= " AND value <> 0";
430  $resql2 = $db->query($sql2);
431  if ($resql2) {
432  $obj2 = $db->fetch_object($resql2);
433  if ($obj2 && $obj2->nb == 0) {
434  // Module not found, so we canremove entry
435  $sqldeletea = "DELETE FROM ".MAIN_DB_PREFIX."boxes WHERE entity = ".((int) $obj->entity)." AND box_id IN (SELECT rowid FROM ".MAIN_DB_PREFIX."boxes_def WHERE file = '".$db->escape($obj->file)."' AND entity = ".((int) $obj->entity).")";
436  $sqldeleteb = "DELETE FROM ".MAIN_DB_PREFIX."boxes_def WHERE file = '".$db->escape($obj->file)."' AND entity = ".((int) $obj->entity);
437 
438  if (GETPOST('standard', 'alpha') == 'confirmed') {
439  $db->query($sqldeletea);
440  $db->query($sqldeleteb);
441 
442  print '<tr><td>Constant '.$obj->file.' set in boxes_def for entity '.$obj->entity.' but MAIN_MODULE_'.strtoupper($module).' not defined in entity '.((int) $obj->entity).', we delete record</td></tr>';
443  } else {
444  print '<tr><td>Constant '.$obj->file.' set in boxes_def for entity '.$obj->entity.' but MAIN_MODULE_'.strtoupper($module).' not defined in entity '.((int) $obj->entity).', we should delete record (not done, mode test)</td></tr>';
445  }
446  } else {
447  //print '<tr><td>Constant '.$obj->name.' set in entity '.$obj->entity.' with value '.$obj->value.' -> Module found in entity '.$obj->entity.', we keep record</td></tr>';
448  }
449  }
450  }
451 
452  $i++;
453  }
454 
455  $db->commit();
456  }
457  }
458 }
459 
460 
461 // restore_thirdparties_logos: Move logos to correct new directory.
462 if ($ok && GETPOST('restore_thirdparties_logos')) {
463  //$exts=array('gif','png','jpg');
464 
465  $ext = '';
466 
467  print '<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
468 
469  $sql = "SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX."societe as s ORDER BY s.nom";
470  $resql = $db->query($sql);
471  if ($resql) {
472  $num = $db->num_rows($resql);
473  $i = 0;
474 
475  while ($i < $num) {
476  $obj = $db->fetch_object($resql);
477 
478  /*
479  $name=preg_replace('/é/','',$obj->name);
480  $name=preg_replace('/ /','_',$name);
481  $name=preg_replace('/\'/','',$name);
482  */
483 
484  $tmp = explode('.', $obj->logo);
485  $name = $tmp[0];
486  if (isset($tmp[1])) {
487  $ext = '.'.$tmp[1];
488  }
489 
490  if (!empty($name)) {
491  $filetotest = $dolibarr_main_data_root.'/societe/logos/'.$name.$ext;
492  $filetotestsmall = $dolibarr_main_data_root.'/societe/logos/thumbs/'.$name.'_small'.$ext;
493  $exists = dol_is_file($filetotest);
494  print 'Check thirdparty '.$obj->rowid.' name='.$obj->name.' logo='.$obj->logo.' file '.$filetotest." exists=".$exists."<br>\n";
495  if ($exists) {
496  $filetarget = $dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos/'.$name.$ext;
497  $filetargetsmall = $dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos/thumbs/'.$name.'_small'.$ext;
498  $existt = dol_is_file($filetarget);
499  if (!$existt) {
500  if (GETPOST('restore_thirdparties_logos', 'alpha') == 'confirmed') {
501  dol_mkdir($dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos');
502  }
503 
504  print " &nbsp; &nbsp; &nbsp; -> Copy file ".$filetotest." -> ".$filetarget."<br>\n";
505  if (GETPOST('restore_thirdparties_logos', 'alpha') == 'confirmed') {
506  dol_copy($filetotest, $filetarget, '', 0);
507  }
508  }
509 
510  $existtt = dol_is_file($filetargetsmall);
511  if (!$existtt) {
512  if (GETPOST('restore_thirdparties_logos', 'alpha') == 'confirmed') {
513  dol_mkdir($dolibarr_main_data_root.'/societe/'.$obj->rowid.'/logos/thumbs');
514  }
515  print " &nbsp; &nbsp; &nbsp; -> Copy file ".$filetotestsmall." -> ".$filetargetsmall."<br>\n";
516  if (GETPOST('restore_thirdparties_logos', 'alpha') == 'confirmed') {
517  dol_copy($filetotestsmall, $filetargetsmall, '', 0);
518  }
519  }
520  }
521  }
522 
523  $i++;
524  }
525  } else {
526  $ok = 0;
527  dol_print_error($db);
528  }
529 
530  print '</td></tr>';
531 }
532 
533 
534 
535 // restore_user_pictures: Move pictures to correct new directory.
536 if ($ok && GETPOST('restore_user_pictures', 'alpha')) {
537  //$exts=array('gif','png','jpg');
538 
539  $ext = '';
540 
541  print '<tr><td colspan="2"><br>*** Restore user pictures<br>';
542 
543  $sql = "SELECT s.rowid, s.firstname, s.lastname, s.login, s.photo FROM ".MAIN_DB_PREFIX."user as s ORDER BY s.rowid";
544  $resql = $db->query($sql);
545  if ($resql) {
546  $num = $db->num_rows($resql);
547  $i = 0;
548 
549  while ($i < $num) {
550  $obj = $db->fetch_object($resql);
551 
552  /*
553  $name=preg_replace('/é/','',$obj->name);
554  $name=preg_replace('/ /','_',$name);
555  $name=preg_replace('/\'/','',$name);
556  */
557 
558  $tmp = explode('.', $obj->photo);
559  $name = $tmp[0];
560  if (isset($tmp[1])) {
561  $ext = '.'.$tmp[1];
562  }
563 
564  if (!empty($name)) {
565  $filetotest = $dolibarr_main_data_root.'/users/'.substr(sprintf('%08d', $obj->rowid), -1, 1).'/'.substr(sprintf('%08d', $obj->rowid), -2, 1).'/'.$name.$ext;
566  $filetotestsmall = $dolibarr_main_data_root.'/users/'.substr(sprintf('%08d', $obj->rowid), -1, 1).'/'.substr(sprintf('%08d', $obj->rowid), -2, 1).'/thumbs/'.$name.'_small'.$ext;
567  $filetotestmini = $dolibarr_main_data_root.'/users/'.substr(sprintf('%08d', $obj->rowid), -1, 1).'/'.substr(sprintf('%08d', $obj->rowid), -2, 1).'/thumbs/'.$name.'_mini'.$ext;
568  $exists = dol_is_file($filetotest);
569  print 'Check user '.$obj->rowid.' lastname='.$obj->lastname.' firstname='.$obj->firstname.' photo='.$obj->photo.' file '.$filetotest." exists=".$exists."<br>\n";
570  if ($exists) {
571  $filetarget = $dolibarr_main_data_root.'/users/'.$obj->rowid.'/'.$name.$ext;
572  $filetargetsmall = $dolibarr_main_data_root.'/users/'.$obj->rowid.'/thumbs/'.$name.'_small'.$ext;
573  $filetargetmini = $dolibarr_main_data_root.'/users/'.$obj->rowid.'/thumbs/'.$name.'_mini'.$ext;
574 
575  $existt = dol_is_file($filetarget);
576  if (!$existt) {
577  if (GETPOST('restore_user_pictures', 'alpha') == 'confirmed') {
578  dol_mkdir($dolibarr_main_data_root.'/users/'.$obj->rowid);
579  }
580 
581  print " &nbsp; &nbsp; &nbsp; -> Copy file ".$filetotest." -> ".$filetarget."<br>\n";
582  if (GETPOST('restore_user_pictures', 'alpha') == 'confirmed') {
583  dol_copy($filetotest, $filetarget, '', 0);
584  }
585  }
586 
587  $existtt = dol_is_file($filetargetsmall);
588  if (!$existtt) {
589  if (GETPOST('restore_user_pictures', 'alpha') == 'confirmed') {
590  dol_mkdir($dolibarr_main_data_root.'/users/'.$obj->rowid.'/thumbs');
591  }
592 
593  print " &nbsp; &nbsp; &nbsp; -> Copy file ".$filetotestsmall." -> ".$filetargetsmall."<br>\n";
594  if (GETPOST('restore_user_pictures', 'alpha') == 'confirmed') {
595  dol_copy($filetotestsmall, $filetargetsmall, '', 0);
596  }
597  }
598 
599  $existtt = dol_is_file($filetargetmini);
600  if (!$existtt) {
601  if (GETPOST('restore_user_pictures', 'alpha') == 'confirmed') {
602  dol_mkdir($dolibarr_main_data_root.'/users/'.$obj->rowid.'/thumbs');
603  }
604 
605  print " &nbsp; &nbsp; &nbsp; -> Copy file ".$filetotestmini." -> ".$filetargetmini."<br>\n";
606  if (GETPOST('restore_user_pictures', 'alpha') == 'confirmed') {
607  dol_copy($filetotestmini, $filetargetmini, '', 0);
608  }
609  }
610  }
611  }
612 
613  $i++;
614  }
615  } else {
616  $ok = 0;
617  dol_print_error($db);
618  }
619 
620  print '</td></tr>';
621 }
622 
623 
624 // rebuild_product_thumbs: Rebuild thumbs for product files
625 if ($ok && GETPOST('rebuild_product_thumbs', 'alpha')) {
626  $ext = '';
627  global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
628 
629  print '<tr><td colspan="2"><br>*** Rebuild product thumbs<br>';
630 
631  $sql = "SELECT s.rowid, s.ref FROM ".MAIN_DB_PREFIX."product as s ORDER BY s.ref";
632  $resql = $db->query($sql);
633  if ($resql) {
634  $num = $db->num_rows($resql);
635  $i = 0;
636 
637  while ($i < $num) {
638  $obj = $db->fetch_object($resql);
639 
640  if (!empty($obj->ref)) {
641  $files = dol_dir_list($dolibarr_main_data_root.'/produit/'.$obj->ref, 'files', 0);
642  foreach ($files as $file) {
643  // Generate thumbs.
644  if (image_format_supported($file['fullname']) == 1) {
645  $imgThumbSmall = 'notbuild';
646  if (GETPOST('rebuild_product_thumbs', 'alpha') == 'confirmed') {
647  // Used on logon for example
648  $imgThumbSmall = vignette($file['fullname'], $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs");
649  }
650  print 'Check product '.$obj->rowid.", file ".$file['fullname']." -> ".$imgThumbSmall." maxwidthsmall=".$maxwidthsmall." maxheightsmall=".$maxheightsmall."<br>\n";
651  $imgThumbMini = 'notbuild';
652  if (GETPOST('rebuild_product_thumbs', 'alpha') == 'confirmed') {
653  // Create mini thumbs for image (Ratio is near 16/9)
654  // Used on menu or for setup page for example
655  $imgThumbMini = vignette($file['fullname'], $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs");
656  }
657  print 'Check product '.$obj->rowid.", file ".$file['fullname']." -> ".$imgThumbMini." maxwidthmini=".$maxwidthmini." maxheightmini=".$maxheightmini."<br>\n";
658  }
659  }
660  }
661 
662  $i++;
663  }
664  } else {
665  $ok = 0;
666  dol_print_error($db);
667  }
668 
669  print '</td></tr>';
670 }
671 
672 // clean_linked_elements: Check and clean linked elements
673 if ($ok && GETPOST('clean_linked_elements', 'alpha')) {
674  print '<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
675  // propal => order
676  print '<tr><td colspan="2">'.checkLinkedElements('propal', 'commande')."</td></tr>\n";
677 
678  // propal => invoice
679  print '<tr><td colspan="2">'.checkLinkedElements('propal', 'facture')."</td></tr>\n";
680 
681  // order => invoice
682  print '<tr><td colspan="2">'.checkLinkedElements('commande', 'facture')."</td></tr>\n";
683 
684  // order => shipping
685  print '<tr><td colspan="2">'.checkLinkedElements('commande', 'shipping')."</td></tr>\n";
686 
687  // shipping => delivery
688  print '<tr><td colspan="2">'.checkLinkedElements('shipping', 'delivery')."</td></tr>\n";
689 
690  // order_supplier => invoice_supplier
691  print '<tr><td colspan="2">'.checkLinkedElements('order_supplier', 'invoice_supplier')."</td></tr>\n";
692 }
693 
694 
695 // clean_menus: Check orphelins menus
696 if ($ok && GETPOST('clean_menus', 'alpha')) {
697  print '<tr><td colspan="2"><br>*** Clean menu entries coming from disabled modules</td></tr>';
698 
699  $sql = "SELECT rowid, module";
700  $sql .= " FROM ".MAIN_DB_PREFIX."menu as c";
701  $sql .= " WHERE module IS NOT NULL AND module <> ''";
702  $sql .= " ORDER BY module";
703 
704  $resql = $db->query($sql);
705  if ($resql) {
706  $num = $db->num_rows($resql);
707  if ($num) {
708  $i = 0;
709  while ($i < $num) {
710  $obj = $db->fetch_object($resql);
711 
712  $modulecond = $obj->module;
713  $modulecondarray = explode('|', $obj->module); // Name of module
714 
715  print '<tr><td>';
716  print $modulecond;
717 
718  $db->begin();
719 
720  if ($modulecond) { // And menu entry for module $modulecond was found in database.
721  $moduleok = 0;
722  foreach ($modulecondarray as $tmpname) {
723  if ($tmpname == 'margins') {
724  $tmpname = 'margin'; // TODO Remove this when normalized
725  }
726 
727  $result = 0;
728  if (!empty($conf->$tmpname)) {
729  $result = $conf->$tmpname->enabled;
730  }
731  if ($result) {
732  $moduleok++;
733  }
734  }
735 
736  if (!$moduleok && $modulecond) {
737  print ' - Module condition '.$modulecond.' seems ko, we delete menu entry.';
738  if (GETPOST('clean_menus') == 'confirmed') {
739  $sql2 = "DELETE FROM ".MAIN_DB_PREFIX."menu WHERE module = '".$db->escape($modulecond)."'";
740  $resql2 = $db->query($sql2);
741  if (!$resql2) {
742  $error++;
743  dol_print_error($db);
744  } else {
745  print ' - <span class="warning">Cleaned</span>';
746  }
747  } else {
748  print ' - <span class="warning">Canceled (test mode)</span>';
749  }
750  } else {
751  print ' - Module condition '.$modulecond.' is ok, we do nothing.';
752  }
753  }
754 
755  if (!$error) {
756  $db->commit();
757  } else {
758  $db->rollback();
759  }
760 
761  print'</td></tr>';
762 
763  if ($error) {
764  break;
765  }
766 
767  $i++;
768  }
769  } else {
770  print '<tr><td>No menu entries of disabled menus found</td></tr>';
771  }
772  } else {
773  dol_print_error($db);
774  }
775 }
776 
777 
778 
779 // clean_orphelin_dir: Run purge of directory
780 if ($ok && GETPOST('clean_orphelin_dir', 'alpha')) {
781  $listmodulepart = array('company', 'invoice', 'invoice_supplier', 'propal', 'order', 'order_supplier', 'contract', 'tax');
782  foreach ($listmodulepart as $modulepart) {
783  $filearray = array();
784  $upload_dir = isset($conf->$modulepart->dir_output) ? $conf->$modulepart->dir_output : '';
785  if ($modulepart == 'company') {
786  $upload_dir = $conf->societe->dir_output; // TODO change for multicompany sharing
787  }
788  if ($modulepart == 'invoice') {
789  $upload_dir = $conf->facture->dir_output;
790  }
791  if ($modulepart == 'invoice_supplier') {
792  $upload_dir = $conf->fournisseur->facture->dir_output;
793  }
794  if ($modulepart == 'order') {
795  $upload_dir = $conf->commande->dir_output;
796  }
797  if ($modulepart == 'order_supplier') {
798  $upload_dir = $conf->fournisseur->commande->dir_output;
799  }
800  if ($modulepart == 'contract') {
801  $upload_dir = $conf->contrat->dir_output;
802  }
803 
804  if (empty($upload_dir)) {
805  continue;
806  }
807 
808  print '<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.'</td></tr>';
809 
810  $filearray = dol_dir_list($upload_dir, "files", 1, '', array('^SPECIMEN\.pdf$', '^\.', '(\.meta|_preview.*\.png)$', '^temp$', '^payments$', '^CVS$', '^thumbs$'), '', SORT_DESC, 1, true);
811 
812  // To show ref or specific information according to view to show (defined by $module)
813  if ($modulepart == 'company') {
814  include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
815  $object_instance = new Societe($db);
816  }
817  if ($modulepart == 'invoice') {
818  include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
819  $object_instance = new Facture($db);
820  } elseif ($modulepart == 'invoice_supplier') {
821  include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
822  $object_instance = new FactureFournisseur($db);
823  } elseif ($modulepart == 'propal') {
824  include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
825  $object_instance = new Propal($db);
826  } elseif ($modulepart == 'order') {
827  include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
828  $object_instance = new Commande($db);
829  } elseif ($modulepart == 'order_supplier') {
830  include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
831  $object_instance = new CommandeFournisseur($db);
832  } elseif ($modulepart == 'contract') {
833  include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
834  $object_instance = new Contrat($db);
835  } elseif ($modulepart == 'tax') {
836  include_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
837  $object_instance = new ChargeSociales($db);
838  }
839 
840  foreach ($filearray as $key => $file) {
841  if (!is_dir($file['name'])
842  && $file['name'] != '.'
843  && $file['name'] != '..'
844  && $file['name'] != 'CVS'
845  ) {
846  // Define relative path used to store the file
847  $relativefile = preg_replace('/'.preg_quote($upload_dir.'/', '/').'/', '', $file['fullname']);
848 
849  //var_dump($file);
850  $id = 0; $ref = ''; $object_instance->id = 0; $object_instance->ref = ''; $label = '';
851 
852  // To show ref or specific information according to view to show (defined by $module)
853  if ($modulepart == 'invoice') {
854  preg_match('/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
855  }
856  if ($modulepart == 'invoice_supplier') {
857  preg_match('/(\d+)\/[^\/]+$/', $relativefile, $reg); $id = empty($reg[1]) ? '' : $reg[1];
858  }
859  if ($modulepart == 'propal') {
860  preg_match('/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
861  }
862  if ($modulepart == 'order') {
863  preg_match('/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
864  }
865  if ($modulepart == 'order_supplier') {
866  preg_match('/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
867  }
868  if ($modulepart == 'contract') {
869  preg_match('/(.*)\/[^\/]+$/', $relativefile, $reg); $ref = $reg[1];
870  }
871  if ($modulepart == 'tax') {
872  preg_match('/(\d+)\/[^\/]+$/', $relativefile, $reg); $id = $reg[1];
873  }
874 
875  if ($id || $ref) {
876  //print 'Fetch '.$id.' or '.$ref.'<br>';
877  $result = $object_instance->fetch($id, $ref);
878  //print $result.'<br>';
879  if ($result == 0) { // Not found but no error
880  // Clean of orphelins directories are done into repair.php
881  print '<tr><td colspan="2">';
882  print 'Delete orphelins file '.$file['fullname'].'<br>';
883  if (GETPOST('clean_orphelin_dir', 'alpha') == 'confirmed') {
884  dol_delete_file($file['fullname'], 1, 1, 1);
885  dol_delete_dir(dirname($file['fullname']), 1);
886  }
887  print "</td></tr>";
888  } elseif ($result < 0) {
889  print 'Error in '.get_class($object_instance).'.fetch of id'.$id.' ref='.$ref.', result='.$result.'<br>';
890  }
891  }
892  }
893  }
894  }
895 }
896 
897 // clean_linked_elements: Check and clean linked elements
898 if ($ok && GETPOST('clean_product_stock_batch', 'alpha')) {
899  $methodtofix = GETPOST('methodtofix', 'alpha') ?GETPOST('methodtofix', 'alpha') : 'updatestock';
900 
901  print '<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.' (possible values: updatestock or updatebatch)</td></tr>';
902 
903  $sql = "SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
904  $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";
905  $sql .= " WHERE p.rowid = ps.fk_product";
906  $sql .= " GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
907  $sql .= " HAVING (SUM(pb.qty) IS NOT NULL AND reel != SUM(pb.qty)) OR (SUM(pb.qty) IS NULL AND p.tobatch > 0)";
908  print $sql;
909  $resql = $db->query($sql);
910  if ($resql) {
911  $num = $db->num_rows($resql);
912 
913  if ($num) {
914  $i = 0;
915  while ($i < $num) {
916  $obj = $db->fetch_object($resql);
917  print '<tr><td>Product '.$obj->rowid.'-'.$obj->ref.' in warehouse id='.$obj->fk_entrepot.' -> product_stock.id='.$obj->psrowid.': '.$obj->reel.' (product_stock.reel) != '.($obj->reelbatch ? $obj->reelbatch : '0').' (sum product_batch)';
918 
919  // Fix is required
920  if ($obj->reel != $obj->reelbatch) {
921  if (empty($obj->tobatch)) {
922  // If product is not a product that support batches, we can clean stock by deleting the product batch lines
923  print ' -> Delete qty '.$obj->reelbatch.' for any lot linked to fk_product_stock='.$obj->psrowid;
924  $sql2 = "DELETE FROM ".MAIN_DB_PREFIX."product_batch";
925  $sql2 .= " WHERE fk_product_stock = ".((int) $obj->psrowid);
926  print '<br>'.$sql2;
927 
928  if (GETPOST('clean_product_stock_batch') == 'confirmed') {
929  $resql2 = $db->query($sql2);
930  if (!$resql2) {
931  $error++;
932  dol_print_error($db);
933  }
934  }
935  } else {
936  if ($methodtofix == 'updatebatch') {
937  // Method 1
938  print ' -> Insert qty '.($obj->reel - $obj->reelbatch).' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
939  $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."product_batch(fk_product_stock, batch, qty)";
940  $sql2 .= "VALUES(".((int) $obj->psrowid).", '000000', ".((float) ($obj->reel - $obj->reelbatch)).")";
941  print '<br>'.$sql2;
942 
943  if (GETPOST('clean_product_stock_batch') == 'confirmed') {
944  $resql2 = $db->query($sql2);
945  if (!$resql2) {
946  // TODO If it fails, we must make update
947  //$sql2 ="UPDATE ".MAIN_DB_PREFIX."product_batch";
948  //$sql2.=" SET ".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
949  //$sql2.=" WHERE fk_product_stock = ".((int) $obj->psrowid)
950  }
951  }
952  }
953  if ($methodtofix == 'updatestock') {
954  // Method 2
955  print ' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((float) $obj->reelbatch) : '0').' for ps.rowid = '.((int) $obj->psrowid);
956  $sql2 = "UPDATE ".MAIN_DB_PREFIX."product_stock";
957  $sql2 .= " SET reel = ".($obj->reelbatch ? ((float) $obj->reelbatch) : '0')." WHERE rowid = ".((int) $obj->psrowid);
958  print '<br>'.$sql2;
959 
960  if (GETPOST('clean_product_stock_batch') == 'confirmed') {
961  $error = 0;
962 
963  $db->begin();
964 
965  $resql2 = $db->query($sql2);
966  if ($resql2) {
967  // We update product_stock, so we must fill p.stock into product too.
968  $sql3 = 'UPDATE '.MAIN_DB_PREFIX.'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid)';
969  $resql3 = $db->query($sql3);
970  if (!$resql3) {
971  $error++;
972  dol_print_error($db);
973  }
974  } else {
975  $error++;
976  dol_print_error($db);
977  }
978 
979  if (!$error) {
980  $db->commit();
981  } else {
982  $db->rollback();
983  }
984  }
985  }
986  }
987  }
988 
989  print'</td></tr>';
990 
991  $i++;
992  }
993  } else {
994  print '<tr><td colspan="2">Nothing to do</td></tr>';
995  }
996  } else {
997  dol_print_error($db);
998  }
999 }
1000 
1001 
1002 // clean_product_stock_negative_if_batch
1003 if ($ok && GETPOST('clean_product_stock_negative_if_batch', 'alpha')) {
1004  print '<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.' (possible values: updatestock or updatebatch)</td></tr>';
1005 
1006  $sql = "SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
1007  $sql .= " FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb";
1008  $sql .= " WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
1009  $sql .= " AND p.tobatch > 0";
1010  $sql .= " GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
1011  $sql .= " HAVING reel != SUM(pb.qty)";
1012  $resql = $db->query($sql);
1013  if ($resql) {
1014  $num = $db->num_rows($resql);
1015 
1016  if ($num) {
1017  $i = 0;
1018  while ($i < $num) {
1019  $obj = $db->fetch_object($resql);
1020  print '<tr><td>'.$obj->rowid.'-'.$obj->ref.'-'.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' != '.$obj->reelbatch;
1021 
1022  // TODO
1023  }
1024  }
1025  }
1026 }
1027 
1028 // set_empty_time_spent_amount
1029 if ($ok && GETPOST('set_empty_time_spent_amount', 'alpha')) {
1030  print '<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
1031 
1032  $sql = "SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
1033  $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."user as u";
1034  $sql .= " WHERE ptt.fk_user = u.rowid";
1035  $sql .= " AND ptt.thm IS NULL and u.thm > 0";
1036  $sql .= " GROUP BY u.rowid, u.login, u.thm";
1037 
1038  $resql = $db->query($sql);
1039  if ($resql) {
1040  $num = $db->num_rows($resql);
1041 
1042  if ($num) {
1043  $i = 0;
1044  while ($i < $num) {
1045  $obj = $db->fetch_object($resql);
1046  print '<tr><td>'.$obj->login.'-'.$obj->user_id.' ('.$obj->nb.' lines to fix) -> '.$obj->user_thm;
1047 
1048  $db->begin();
1049 
1050  if (GETPOST('set_empty_time_spent_amount') == 'confirmed') {
1051  $sql2 = "UPDATE ".MAIN_DB_PREFIX."projet_task_time";
1052  $sql2 .= " SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id);
1053  $resql2 = $db->query($sql2);
1054  if (!$resql2) {
1055  $error++;
1056  dol_print_error($db);
1057  }
1058  }
1059 
1060  if (!$error) {
1061  $db->commit();
1062  } else {
1063  $db->rollback();
1064  }
1065 
1066  print'</td></tr>';
1067 
1068  if ($error) {
1069  break;
1070  }
1071 
1072  $i++;
1073  }
1074  } else {
1075  print '<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
1076  }
1077  } else {
1078  dol_print_error($db);
1079  }
1080 }
1081 
1082 
1083 // force_disable_of_modules_not_found
1084 if ($ok && GETPOST('force_disable_of_modules_not_found', 'alpha')) {
1085  print '<tr><td colspan="2"><br>*** Force modules not found physicaly to be disabled (only modules adding js, css or hooks can be detected as removed physicaly)</td></tr>';
1086 
1087  $arraylistofkey = array('hooks', 'js', 'css');
1088 
1089  foreach ($arraylistofkey as $key) {
1090  $sql = "SELECT DISTINCT name, value";
1091  $sql .= " FROM ".MAIN_DB_PREFIX."const as c";
1092  $sql .= " WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($key)."'";
1093  $sql .= " ORDER BY name";
1094 
1095  $resql = $db->query($sql);
1096  if ($resql) {
1097  $num = $db->num_rows($resql);
1098  if ($num) {
1099  $i = 0;
1100  while ($i < $num) {
1101  $obj = $db->fetch_object($resql);
1102  $constantname = $obj->name; // Name of constant for hook or js or css declaration
1103 
1104  print '<tr><td>';
1105  print dol_escape_htmltag($constantname);
1106 
1107  $db->begin();
1108 
1109  $reg = array();
1110  if (preg_match('/MAIN_MODULE_(.*)_'.strtoupper($key).'/i', $constantname, $reg)) {
1111  $name = strtolower($reg[1]);
1112 
1113  if ($name) { // An entry for key $key and module $name was found in database.
1114  $reloffile = '';
1115  $result = 'found';
1116 
1117  if ($key == 'hooks') {
1118  $reloffile = $name.'/class/actions_'.$name.'.class.php';
1119  }
1120  if ($key == 'js') {
1121  $value = $obj->value;
1122  $valuearray = (array) json_decode($value); // Force cast into array because sometimes it is a stdClass
1123  $reloffile = $valuearray[0];
1124  $reloffile = preg_replace('/^\//', '', $valuearray[0]);
1125  }
1126  if ($key == 'css') {
1127  $value = $obj->value;
1128  $valuearray = (array) json_decode($value); // Force cast into array because sometimes it is a stdClass
1129  if ($value && (!is_array($valuearray) || count($valuearray) == 0)) {
1130  $valuearray = array();
1131  $valuearray[0] = $value; // If value was not a json array but a string
1132  }
1133  $reloffile = preg_replace('/^\//', '', $valuearray[0]);
1134  }
1135 
1136  if ($reloffile) {
1137  //var_dump($key.' - '.$value.' - '.$reloffile);
1138  try {
1139  $result = dol_buildpath($reloffile, 0, 2);
1140  } catch (Exception $e) {
1141  $result = 'found'; // If error, we force like if we found to avoid any deletion
1142  }
1143  } else {
1144  $result = 'found'; //
1145  }
1146 
1147  if (!$result) {
1148  print ' - File of '.$key.' ('.$reloffile.') NOT found, we disable the module.';
1149  if (GETPOST('force_disable_of_modules_not_found') == 'confirmed') {
1150  $sql2 = "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = 'MAIN_MODULE_".strtoupper($name)."_".strtoupper($key)."'";
1151  $resql2 = $db->query($sql2);
1152  if (!$resql2) {
1153  $error++;
1154  dol_print_error($db);
1155  }
1156  $sql3 = "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = 'MAIN_MODULE_".strtoupper($name)."'";
1157  $resql3 = $db->query($sql3);
1158  if (!$resql3) {
1159  $error++;
1160  dol_print_error($db);
1161  } else {
1162  print ' - <span class="warning">Cleaned</span>';
1163  }
1164  } else {
1165  print ' - <span class="warning">Canceled (test mode)</span>';
1166  }
1167  } else {
1168  print ' - File of '.$key.' ('.$reloffile.') found, we do nothing.';
1169  }
1170  }
1171 
1172  if (!$error) {
1173  $db->commit();
1174  } else {
1175  $db->rollback();
1176  }
1177  }
1178 
1179  print'</td></tr>';
1180 
1181  if ($error) {
1182  break;
1183  }
1184 
1185  $i++;
1186  }
1187  } else {
1188  print '<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).'</td></tr>';
1189  }
1190  } else {
1191  dol_print_error($db);
1192  }
1193  }
1194 }
1195 
1196 
1197 // clean_old_module_entries: Clean data into const when files of module were removed without being
1198 if ($ok && GETPOST('clean_perm_table', 'alpha')) {
1199  print '<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1200 
1201  $listofmods = '';
1202  foreach ($conf->modules as $key => $val) {
1203  $listofmods .= ($listofmods ? ',' : '')."'".$db->escape($val)."'";
1204  }
1205 
1206  $sql = "SELECT id, libelle as label, module from ".MAIN_DB_PREFIX."rights_def WHERE module NOT IN (".$db->sanitize($listofmods, 1).") AND id > 100000";
1207 
1208  $resql = $db->query($sql);
1209  if ($resql) {
1210  $num = $db->num_rows($resql);
1211  if ($num) {
1212  $i = 0;
1213  while ($i < $num) {
1214  $obj = $db->fetch_object($resql);
1215  if ($obj->id > 0) {
1216  print '<tr><td>Found line with id '.$obj->id.', label "'.$obj->label.'" of module "'.$obj->module.'" to delete';
1217  if (GETPOST('clean_perm_table', 'alpha') == 'confirmed') {
1218  $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."rights_def WHERE id = ".((int) $obj->id);
1219  $resqldelete = $db->query($sqldelete);
1220  if (!$resqldelete) {
1221  dol_print_error($db);
1222  }
1223  print ' - deleted';
1224  }
1225  print '</td></tr>';
1226  }
1227  $i++;
1228  }
1229  } else {
1230  print '<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1231  }
1232  } else {
1233  dol_print_error($db);
1234  }
1235 }
1236 
1237 
1238 
1239 // force utf8 on tables
1240 if ($ok && GETPOST('force_utf8_on_tables', 'alpha')) {
1241  print '<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8/utf8_unicode_ci and row_format=dynamic (for mysql/mariadb only)</td></tr>';
1242 
1243  if ($db->type == "mysql" || $db->type == "mysqli") {
1244  $force_utf8_on_tables = GETPOST('force_utf8_on_tables', 'alpha');
1245 
1246  $listoftables = $db->DDLListTables($db->database_name);
1247 
1248  // Disable foreign key checking for avoid errors
1249  if ($force_utf8_on_tables == 'confirmed') {
1250  $sql = 'SET FOREIGN_KEY_CHECKS=0';
1251  print '<!-- '.$sql.' -->';
1252  $resql = $db->query($sql);
1253  }
1254 
1255  foreach ($listoftables as $table) {
1256  // do not convert llx_const if mysql encrypt/decrypt is used
1257  if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match('/\_const$/', $table)) {
1258  continue;
1259  }
1260 
1261  print '<tr><td colspan="2">';
1262  print $table;
1263  $sql1 = "ALTER TABLE ".$table." ROW_FORMAT=dynamic";
1264  $sql2 = "ALTER TABLE ".$table." CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci";
1265  print '<!-- '.$sql1.' -->';
1266  print '<!-- '.$sql2.' -->';
1267  if ($force_utf8_on_tables == 'confirmed') {
1268  $resql1 = $db->query($sql1);
1269  if ($resql1) {
1270  $resql2 = $db->query($sql2);
1271  } else {
1272  $resql2 = false;
1273  }
1274  print ' - Done ('.(($resql1 && $resql2) ? 'OK' : 'KO').')';
1275  } else {
1276  print ' - Disabled';
1277  }
1278  print '</td></tr>';
1279  }
1280 
1281  // Enable foreign key checking
1282  if ($force_utf8_on_tables == 'confirmed') {
1283  $sql = 'SET FOREIGN_KEY_CHECKS=1';
1284  print '<!-- '.$sql.' -->';
1285  $resql = $db->query($sql);
1286  }
1287  } else {
1288  print '<tr><td colspan="2">Not available with database type '.$db->type.'</td></tr>';
1289  }
1290 }
1291 
1292 // force utf8mb4 on tables EXPERIMENTAL !
1293 if ($ok && GETPOST('force_utf8mb4_on_tables', 'alpha')) {
1294  print '<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8mb4/utf8mb4_unicode_ci (for mysql/mariadb only)</td></tr>';
1295 
1296  if ($db->type == "mysql" || $db->type == "mysqli") {
1297  $force_utf8mb4_on_tables = GETPOST('force_utf8mb4_on_tables', 'alpha');
1298 
1299  $listoftables = $db->DDLListTables($db->database_name);
1300 
1301  // Disable foreign key checking for avoid errors
1302  if ($force_utf8mb4_on_tables == 'confirmed') {
1303  $sql = 'SET FOREIGN_KEY_CHECKS=0';
1304  print '<!-- '.$sql.' -->';
1305  $resql = $db->query($sql);
1306  }
1307 
1308  foreach ($listoftables as $table) {
1309  // do not convert llx_const if mysql encrypt/decrypt is used
1310  if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match('/\_const$/', $table)) {
1311  continue;
1312  }
1313 
1314  print '<tr><td colspan="2">';
1315  print $table;
1316  $sql1 = "ALTER TABLE ".$table." ROW_FORMAT=dynamic";
1317  $sql2 = "ALTER TABLE ".$table." CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
1318  print '<!-- '.$sql1.' -->';
1319  print '<!-- '.$sql2.' -->';
1320  if ($force_utf8mb4_on_tables == 'confirmed') {
1321  $resql1 = $db->query($sql1);
1322  if ($resql1) {
1323  $resql2 = $db->query($sql2);
1324  } else {
1325  $resql2 = false;
1326  }
1327  print ' - Done ('.(($resql1 && $resql2) ? 'OK' : 'KO').')';
1328  } else {
1329  print ' - Disabled';
1330  }
1331  print '</td></tr>';
1332  flush();
1333  ob_flush();
1334  }
1335 
1336  // Enable foreign key checking
1337  if ($force_utf8mb4_on_tables == 'confirmed') {
1338  $sql = 'SET FOREIGN_KEY_CHECKS=1';
1339  print '<!-- '.$sql.' -->';
1340  $resql = $db->query($sql);
1341  }
1342  } else {
1343  print '<tr><td colspan="2">Not available with database type '.$db->type.'</td></tr>';
1344  }
1345 }
1346 
1347 // rebuild sequences for pgsql
1348 if ($ok && GETPOST('rebuild_sequences', 'alpha')) {
1349  print '<tr><td colspan="2"><br>*** Force to rebuild sequences (for postgresql only)</td></tr>';
1350 
1351  if ($db->type == "pgsql") {
1352  $rebuild_sequence = GETPOST('rebuild_sequences', 'alpha');
1353 
1354  if ($rebuild_sequence == 'confirmed') {
1355  $sql = "SELECT dol_util_rebuild_sequences();";
1356  print '<!-- '.$sql.' -->';
1357  $resql = $db->query($sql);
1358  }
1359  } else {
1360  print '<tr><td colspan="2">Not available with database type '.$db->type.'</td></tr>';
1361  }
1362 }
1363 
1364 //
1365 if ($ok && GETPOST('repair_link_dispatch_lines_supplier_order_lines')) {
1366  /*
1367  * This script is meant to be run when upgrading from a dolibarr version < 3.8
1368  * to a newer version.
1369  *
1370  * Version 3.8 introduces a new column in llx_commande_fournisseur_dispatch, which
1371  * matches the dispatch to a specific supplier order line (so that if there are
1372  * several with the same product, the user can specifically tell which products of
1373  * which line were dispatched where).
1374  *
1375  * However when migrating, the new column has a default value of 0, which means that
1376  * old supplier orders whose lines were dispatched using the old dolibarr version
1377  * have unspecific dispatch lines, which are not taken into account by the new version,
1378  * thus making the order look like it was never dispatched at all.
1379  *
1380  * This scripts sets this foreign key to the first matching supplier order line whose
1381  * product (and supplier order of course) are the same as the dispatch’s.
1382  *
1383  * If the dispatched quantity is more than indicated on the order line (this happens if
1384  * there are several order lines for the same product), it creates new dispatch lines
1385  * pointing to the other order lines accordingly, until all the dispatched quantity is
1386  * accounted for.
1387  */
1388 
1389  $repair_link_dispatch_lines_supplier_order_lines = GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha');
1390 
1391 
1392  echo '<tr><th>Repair llx_commande_fournisseur_dispatch.fk_commandefourndet</th></tr>';
1393  echo '<tr><td>Repair in progress. This may take a while.</td></tr>';
1394 
1395  $sql_dispatch = 'SELECT * FROM '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch WHERE COALESCE(fk_commandefourndet, 0) = 0';
1396  $db->begin();
1397  $resql_dispatch = $db->query($sql_dispatch);
1398  $n_processed_rows = 0;
1399  $errors = array();
1400  if ($resql_dispatch) {
1401  if ($db->num_rows($resql_dispatch) == 0) {
1402  echo '<tr><td>Nothing to do.</td></tr>';
1403  exit;
1404  }
1405  while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
1406  $sql_line = 'SELECT line.rowid, line.qty FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet AS line';
1407  $sql_line .= ' WHERE line.fk_commande = '.((int) $obj_dispatch->fk_commande);
1408  $sql_line .= ' AND line.fk_product = '.((int) $obj_dispatch->fk_product);
1409  $resql_line = $db->query($sql_line);
1410 
1411  // s’il y a plusieurs lignes avec le même produit sur cette commande fournisseur,
1412  // on divise la ligne de dispatch en autant de lignes qu’on en a sur la commande pour le produit
1413  // et on met la quantité de la ligne dans la limite du "budget" indiqué par dispatch.qty
1414 
1415  $remaining_qty = $obj_dispatch->qty;
1416  $first_iteration = true;
1417  if (!$resql_line) {
1418  echo '<tr><td>Unable to find a matching supplier order line for dispatch #'.$obj_dispatch->rowid.'</td></tr>';
1419  $errors[] = $sql_line;
1420  $n_processed_rows++;
1421  continue;
1422  }
1423  if ($db->num_rows($resql_line) == 0) {
1424  continue;
1425  }
1426  while ($obj_line = $db->fetch_object($resql_line)) {
1427  if (!$remaining_qty) {
1428  break;
1429  }
1430  if (!$obj_line->rowid) {
1431  continue;
1432  }
1433  $qty_for_line = min($remaining_qty, $obj_line->qty);
1434  if ($first_iteration) {
1435  $sql_attach = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch';
1436  $sql_attach .= ' SET fk_commandefourndet = '.((int) $obj_line->rowid).', qty = '.((float) $qty_for_line);
1437  $sql_attach .= ' WHERE rowid = '.((int) $obj_dispatch->rowid);
1438  $first_iteration = false;
1439  } else {
1440  $sql_attach_values = array(
1441  ((int) $obj_dispatch->fk_commande),
1442  ((int) $obj_dispatch->fk_product),
1443  ((int) $obj_line->rowid),
1444  ((float) $qty_for_line),
1445  ((int) $obj_dispatch->fk_entrepot),
1446  ((int) $obj_dispatch->fk_user),
1447  $obj_dispatch->datec ? "'".$db->idate($db->jdate($obj_dispatch->datec))."'" : 'NULL',
1448  $obj_dispatch->comment ? "'".$db->escape($obj_dispatch->comment)."'" : 'NULL',
1449  $obj_dispatch->status ? ((int) $obj_dispatch->status) : 'NULL',
1450  $obj_dispatch->tms ? "'".$db->idate($db->jdate($obj_dispatch->tms))."'" : 'NULL',
1451  $obj_dispatch->batch ? "'".$db->escape($obj_dispatch->batch)."'" : 'NULL',
1452  $obj_dispatch->eatby ? "'".$db->escape($obj_dispatch->eatby)."'" : 'NULL',
1453  $obj_dispatch->sellby ? "'".$db->escape($obj_dispatch->sellby)."'" : 'NULL'
1454  );
1455  $sql_attach_values = join(', ', $sql_attach_values);
1456 
1457  $sql_attach = 'INSERT INTO '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch';
1458  $sql_attach .= ' (fk_commande, fk_product, fk_commandefourndet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)';
1459  $sql_attach .= " VALUES (".$sql_attach_values.")";
1460  }
1461 
1462  if ($repair_link_dispatch_lines_supplier_order_lines == 'confirmed') {
1463  $resql_attach = $db->query($sql_attach);
1464  } else {
1465  $resql_attach = true; // Force success in test mode
1466  }
1467 
1468  if ($resql_attach) {
1469  $remaining_qty -= $qty_for_line;
1470  } else {
1471  $errors[] = $sql_attach;
1472  }
1473 
1474  $first_iteration = false;
1475  }
1476  $n_processed_rows++;
1477 
1478  // report progress every 256th row
1479  if (!($n_processed_rows & 0xff)) {
1480  echo '<tr><td>Processed '.$n_processed_rows.' rows with '.count($errors).' errors…'."</td></tr>\n";
1481  flush();
1482  ob_flush();
1483  }
1484  }
1485  } else {
1486  echo '<tr><td>Unable to find any dispatch without an fk_commandefourndet.'."</td></tr>\n";
1487  echo $sql_dispatch."\n";
1488  }
1489  echo '<tr><td>Fixed '.$n_processed_rows.' rows with '.count($errors).' errors…'."</td></tr>\n";
1490  echo '<tr><td>DONE.'."</td></tr>\n";
1491 
1492  if (count($errors)) {
1493  $db->rollback();
1494  echo '<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
1495  } else {
1496  $db->commit();
1497  }
1498  $db->close();
1499 
1500  echo '<tr><td><h3>SQL queries with errors:</h3></tr></td>';
1501  echo '<tr><td>'.join('</td></tr><tr><td>', $errors).'</td></tr>';
1502 }
1503 
1504 print '</table>';
1505 
1506 
1507 
1508 if (empty($actiondone)) {
1509  print '<div class="error">'.$langs->trans("ErrorWrongParameters").'</div>';
1510 }
1511 
1512 if ($oneoptionset) {
1513  print '<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(GETPOSTISSET("login") ? '&username='.urlencode(GETPOST("login")) : '').'">';
1514  print $langs->trans("GoToDolibarr");
1515  print '</a></div>';
1516 } else {
1517  print '<div class="center warning" style="padding-top: 10px">';
1518  print $langs->trans("SetAtLeastOneOptionAsUrlParameter");
1519  print '</div>';
1520 }
1521 
1522 dolibarr_install_syslog("--- repair: end");
1523 pFooter(1, $setuplang);
1524 
1525 if ($db->connected) {
1526  $db->close();
1527 }
1528 
1529 // Return code if ran from command line
1530 if (!$ok && isset($argv[1])) {
1531  exit(1);
1532 }
run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='', $okerror='default', $linelengthlimit=32768, $nocommentremoval=0, $offsetforchartofaccount=0, $colspan=0, $onlysqltoimportwebsite=0)
Launch a sql file.
Definition: admin.lib.php:167
Classe permettant la gestion des paiements des charges La tva collectee n'est calculee que sur les fa...
Class to manage predefined suppliers products.
Class to manage customers orders.
Class to manage contracts.
Class to manage standard extra fields.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
Copy a file to another file.
Definition: files.lib.php:713
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
Definition: files.lib.php:1251
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
Definition: files.lib.php:1377
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:481
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:61
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
getDoliDBInstance($type, $host, $user, $pass, $name, $port)
Return a DoliDB instance (database handler).
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:511
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
Definition: images.lib.php:80
pHeader($subtitle, $next, $action='set', $param='', $forcejqueryurl='', $csstable='main-inside')
Show HTML header of install pages.
Definition: inc.php:401
pFooter($nonext=0, $setuplang='', $jscheckfunction='', $withpleasewait=0, $morehtml='')
Print HTML footer of install pages.
Definition: inc.php:490
dolibarr_install_syslog($message, $level=LOG_DEBUG)
Log function for install pages.
Definition: inc.php:551
div float
Buy price without taxes.
Definition: style.css.php:913
clean_data_ecm_directories()
Clean data into ecm_directories table.
Definition: repair.lib.php:130
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.