dolibarr  x.y.z
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 .= " AND p.tobatch > 0";
907  $sql .= " GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
908  $sql .= " HAVING reel != SUM(pb.qty) or SUM(pb.qty) IS NULL";
909  print $sql;
910  $resql = $db->query($sql);
911  if ($resql) {
912  $num = $db->num_rows($resql);
913 
914  if ($num) {
915  $i = 0;
916  while ($i < $num) {
917  $obj = $db->fetch_object($resql);
918  print '<tr><td>Product '.$obj->rowid.'-'.$obj->ref.' in warehouse '.$obj->fk_entrepot.' (product_stock id '.$obj->psrowid.'): '.$obj->reel.' (Stock product_stock.reel) != '.($obj->reelbatch ? $obj->reelbatch : '0').' (Stock batch sum product_batch)';
919 
920  // Fix
921  if ($obj->reel != $obj->reelbatch) {
922  if ($methodtofix == 'updatebatch') {
923  // Method 1
924  print ' -> Insert qty '.($obj->reel - $obj->reelbatch).' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
925  if (GETPOST('clean_product_stock_batch') == 'confirmed') {
926  $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."product_batch(fk_product_stock, batch, qty)";
927  $sql2 .= "VALUES(".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
928  $resql2 = $db->query($sql2);
929  if (!$resql2) {
930  // TODO If it fails, we must make update
931  //$sql2 ="UPDATE ".MAIN_DB_PREFIX."product_batch";
932  //$sql2.=" SET ".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
933  //$sql2.=" WHERE fk_product_stock = ".((int) $obj->psrowid)
934  }
935  }
936  }
937  if ($methodtofix == 'updatestock') {
938  // Method 2
939  print ' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((float) $obj->reelbatch) : '0').' for ps.rowid = '.((int) $obj->psrowid);
940  if (GETPOST('clean_product_stock_batch') == 'confirmed') {
941  $error = 0;
942 
943  $db->begin();
944 
945  $sql2 = "UPDATE ".MAIN_DB_PREFIX."product_stock";
946  $sql2 .= " SET reel = ".($obj->reelbatch ? ((float) $obj->reelbatch) : '0')." WHERE rowid = ".((int) $obj->psrowid);
947  $resql2 = $db->query($sql2);
948  if ($resql2) {
949  // We update product_stock, so we must fill p.stock into product too.
950  $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)';
951  $resql3 = $db->query($sql3);
952  if (!$resql3) {
953  $error++;
954  dol_print_error($db);
955  }
956  } else {
957  $error++;
958  dol_print_error($db);
959  }
960 
961  if (!$error) {
962  $db->commit();
963  } else {
964  $db->rollback();
965  }
966  }
967  }
968  }
969 
970  print'</td></tr>';
971 
972  $i++;
973  }
974  } else {
975  print '<tr><td colspan="2">Nothing to do</td></tr>';
976  }
977  } else {
978  dol_print_error($db);
979  }
980 }
981 
982 
983 // clean_product_stock_negative_if_batch
984 if ($ok && GETPOST('clean_product_stock_negative_if_batch', 'alpha')) {
985  print '<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.' (possible values: updatestock or updatebatch)</td></tr>';
986 
987  $sql = "SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
988  $sql .= " FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb";
989  $sql .= " WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
990  $sql .= " AND p.tobatch > 0";
991  $sql .= " GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
992  $sql .= " HAVING reel != SUM(pb.qty)";
993  $resql = $db->query($sql);
994  if ($resql) {
995  $num = $db->num_rows($resql);
996 
997  if ($num) {
998  $i = 0;
999  while ($i < $num) {
1000  $obj = $db->fetch_object($resql);
1001  print '<tr><td>'.$obj->rowid.'-'.$obj->ref.'-'.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' != '.$obj->reelbatch;
1002 
1003  // TODO
1004  }
1005  }
1006  }
1007 }
1008 
1009 // set_empty_time_spent_amount
1010 if ($ok && GETPOST('set_empty_time_spent_amount', 'alpha')) {
1011  print '<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
1012 
1013  $sql = "SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
1014  $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."user as u";
1015  $sql .= " WHERE ptt.fk_user = u.rowid";
1016  $sql .= " AND ptt.thm IS NULL and u.thm > 0";
1017  $sql .= " GROUP BY u.rowid, u.login, u.thm";
1018 
1019  $resql = $db->query($sql);
1020  if ($resql) {
1021  $num = $db->num_rows($resql);
1022 
1023  if ($num) {
1024  $i = 0;
1025  while ($i < $num) {
1026  $obj = $db->fetch_object($resql);
1027  print '<tr><td>'.$obj->login.'-'.$obj->user_id.' ('.$obj->nb.' lines to fix) -> '.$obj->user_thm;
1028 
1029  $db->begin();
1030 
1031  if (GETPOST('set_empty_time_spent_amount') == 'confirmed') {
1032  $sql2 = "UPDATE ".MAIN_DB_PREFIX."projet_task_time";
1033  $sql2 .= " SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id);
1034  $resql2 = $db->query($sql2);
1035  if (!$resql2) {
1036  $error++;
1037  dol_print_error($db);
1038  }
1039  }
1040 
1041  if (!$error) {
1042  $db->commit();
1043  } else {
1044  $db->rollback();
1045  }
1046 
1047  print'</td></tr>';
1048 
1049  if ($error) {
1050  break;
1051  }
1052 
1053  $i++;
1054  }
1055  } else {
1056  print '<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
1057  }
1058  } else {
1059  dol_print_error($db);
1060  }
1061 }
1062 
1063 
1064 // force_disable_of_modules_not_found
1065 if ($ok && GETPOST('force_disable_of_modules_not_found', 'alpha')) {
1066  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>';
1067 
1068  $arraylistofkey = array('hooks', 'js', 'css');
1069 
1070  foreach ($arraylistofkey as $key) {
1071  $sql = "SELECT DISTINCT name, value";
1072  $sql .= " FROM ".MAIN_DB_PREFIX."const as c";
1073  $sql .= " WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($key)."'";
1074  $sql .= " ORDER BY name";
1075 
1076  $resql = $db->query($sql);
1077  if ($resql) {
1078  $num = $db->num_rows($resql);
1079  if ($num) {
1080  $i = 0;
1081  while ($i < $num) {
1082  $obj = $db->fetch_object($resql);
1083  $constantname = $obj->name; // Name of constant for hook or js or css declaration
1084 
1085  print '<tr><td>';
1086  print dol_escape_htmltag($constantname);
1087 
1088  $db->begin();
1089 
1090  $reg = array();
1091  if (preg_match('/MAIN_MODULE_(.*)_'.strtoupper($key).'/i', $constantname, $reg)) {
1092  $name = strtolower($reg[1]);
1093 
1094  if ($name) { // An entry for key $key and module $name was found in database.
1095  $reloffile = '';
1096  $result = 'found';
1097 
1098  if ($key == 'hooks') {
1099  $reloffile = $name.'/class/actions_'.$name.'.class.php';
1100  }
1101  if ($key == 'js') {
1102  $value = $obj->value;
1103  $valuearray = json_decode($value);
1104  $reloffile = $valuearray[0];
1105  $reloffile = preg_replace('/^\//', '', $valuearray[0]);
1106  }
1107  if ($key == 'css') {
1108  $value = $obj->value;
1109  $valuearray = json_decode($value);
1110  if ($value && (!is_array($valuearray) || count($valuearray) == 0)) {
1111  $valuearray = array();
1112  $valuearray[0] = $value; // If value was not a json array but a string
1113  }
1114  $reloffile = preg_replace('/^\//', '', $valuearray[0]);
1115  }
1116 
1117  if ($reloffile) {
1118  //var_dump($key.' - '.$value.' - '.$reloffile);
1119  try {
1120  $result = dol_buildpath($reloffile, 0, 2);
1121  } catch (Exception $e) {
1122  $result = 'found'; // If error, we force like if we found to avoid any deletion
1123  }
1124  } else {
1125  $result = 'found'; //
1126  }
1127 
1128  if (!$result) {
1129  print ' - File of '.$key.' ('.$reloffile.') NOT found, we disable the module.';
1130  if (GETPOST('force_disable_of_modules_not_found') == 'confirmed') {
1131  $sql2 = "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = 'MAIN_MODULE_".strtoupper($name)."_".strtoupper($key)."'";
1132  $resql2 = $db->query($sql2);
1133  if (!$resql2) {
1134  $error++;
1135  dol_print_error($db);
1136  }
1137  $sql3 = "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = 'MAIN_MODULE_".strtoupper($name)."'";
1138  $resql3 = $db->query($sql3);
1139  if (!$resql3) {
1140  $error++;
1141  dol_print_error($db);
1142  } else {
1143  print ' - <span class="warning">Cleaned</span>';
1144  }
1145  } else {
1146  print ' - <span class="warning">Canceled (test mode)</span>';
1147  }
1148  } else {
1149  print ' - File of '.$key.' ('.$reloffile.') found, we do nothing.';
1150  }
1151  }
1152 
1153  if (!$error) {
1154  $db->commit();
1155  } else {
1156  $db->rollback();
1157  }
1158  }
1159 
1160  print'</td></tr>';
1161 
1162  if ($error) {
1163  break;
1164  }
1165 
1166  $i++;
1167  }
1168  } else {
1169  print '<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).'</td></tr>';
1170  }
1171  } else {
1172  dol_print_error($db);
1173  }
1174  }
1175 }
1176 
1177 
1178 // clean_old_module_entries: Clean data into const when files of module were removed without being
1179 if ($ok && GETPOST('clean_perm_table', 'alpha')) {
1180  print '<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1181 
1182  $listofmods = '';
1183  foreach ($conf->modules as $key => $val) {
1184  $listofmods .= ($listofmods ? ',' : '')."'".$db->escape($val)."'";
1185  }
1186 
1187  $sql = "SELECT id, libelle as label, module from ".MAIN_DB_PREFIX."rights_def WHERE module NOT IN (".$db->sanitize($listofmods, 1).") AND id > 100000";
1188 
1189  $resql = $db->query($sql);
1190  if ($resql) {
1191  $num = $db->num_rows($resql);
1192  if ($num) {
1193  $i = 0;
1194  while ($i < $num) {
1195  $obj = $db->fetch_object($resql);
1196  if ($obj->id > 0) {
1197  print '<tr><td>Found line with id '.$obj->id.', label "'.$obj->label.'" of module "'.$obj->module.'" to delete';
1198  if (GETPOST('clean_perm_table', 'alpha') == 'confirmed') {
1199  $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."rights_def WHERE id = ".((int) $obj->id);
1200  $resqldelete = $db->query($sqldelete);
1201  if (!$resqldelete) {
1202  dol_print_error($db);
1203  }
1204  print ' - deleted';
1205  }
1206  print '</td></tr>';
1207  }
1208  $i++;
1209  }
1210  } else {
1211  print '<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1212  }
1213  } else {
1214  dol_print_error($db);
1215  }
1216 }
1217 
1218 
1219 
1220 // force utf8 on tables
1221 if ($ok && GETPOST('force_utf8_on_tables', 'alpha')) {
1222  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>';
1223 
1224  if ($db->type == "mysql" || $db->type == "mysqli") {
1225  $force_utf8_on_tables = GETPOST('force_utf8_on_tables', 'alpha');
1226 
1227  $listoftables = $db->DDLListTables($db->database_name);
1228 
1229  // Disable foreign key checking for avoid errors
1230  if ($force_utf8_on_tables == 'confirmed') {
1231  $sql = 'SET FOREIGN_KEY_CHECKS=0';
1232  print '<!-- '.$sql.' -->';
1233  $resql = $db->query($sql);
1234  }
1235 
1236  foreach ($listoftables as $table) {
1237  // do not convert llx_const if mysql encrypt/decrypt is used
1238  if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match('/\_const$/', $table)) {
1239  continue;
1240  }
1241 
1242  print '<tr><td colspan="2">';
1243  print $table;
1244  $sql1 = "ALTER TABLE ".$table." ROW_FORMAT=dynamic";
1245  $sql2 = "ALTER TABLE ".$table." CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci";
1246  print '<!-- '.$sql1.' -->';
1247  print '<!-- '.$sql2.' -->';
1248  if ($force_utf8_on_tables == 'confirmed') {
1249  $resql1 = $db->query($sql1);
1250  if ($resql1) {
1251  $resql2 = $db->query($sql2);
1252  } else {
1253  $resql2 = false;
1254  }
1255  print ' - Done ('.(($resql1 && $resql2) ? 'OK' : 'KO').')';
1256  } else {
1257  print ' - Disabled';
1258  }
1259  print '</td></tr>';
1260  }
1261 
1262  // Enable foreign key checking
1263  if ($force_utf8_on_tables == 'confirmed') {
1264  $sql = 'SET FOREIGN_KEY_CHECKS=1';
1265  print '<!-- '.$sql.' -->';
1266  $resql = $db->query($sql);
1267  }
1268  } else {
1269  print '<tr><td colspan="2">Not available with database type '.$db->type.'</td></tr>';
1270  }
1271 }
1272 
1273 // force utf8mb4 on tables EXPERIMENTAL !
1274 if ($ok && GETPOST('force_utf8mb4_on_tables', 'alpha')) {
1275  print '<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8mb4/utf8mb4_unicode_ci (for mysql/mariadb only)</td></tr>';
1276 
1277  if ($db->type == "mysql" || $db->type == "mysqli") {
1278  $force_utf8mb4_on_tables = GETPOST('force_utf8mb4_on_tables', 'alpha');
1279 
1280  $listoftables = $db->DDLListTables($db->database_name);
1281 
1282  // Disable foreign key checking for avoid errors
1283  if ($force_utf8mb4_on_tables == 'confirmed') {
1284  $sql = 'SET FOREIGN_KEY_CHECKS=0';
1285  print '<!-- '.$sql.' -->';
1286  $resql = $db->query($sql);
1287  }
1288 
1289  foreach ($listoftables as $table) {
1290  // do not convert llx_const if mysql encrypt/decrypt is used
1291  if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match('/\_const$/', $table)) {
1292  continue;
1293  }
1294 
1295  print '<tr><td colspan="2">';
1296  print $table;
1297  $sql1 = "ALTER TABLE ".$table." ROW_FORMAT=dynamic";
1298  $sql2 = "ALTER TABLE ".$table." CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
1299  print '<!-- '.$sql1.' -->';
1300  print '<!-- '.$sql2.' -->';
1301  if ($force_utf8mb4_on_tables == 'confirmed') {
1302  $resql1 = $db->query($sql1);
1303  if ($resql1) {
1304  $resql2 = $db->query($sql2);
1305  } else {
1306  $resql2 = false;
1307  }
1308  print ' - Done ('.(($resql1 && $resql2) ? 'OK' : 'KO').')';
1309  } else {
1310  print ' - Disabled';
1311  }
1312  print '</td></tr>';
1313  flush();
1314  ob_flush();
1315  }
1316 
1317  // Enable foreign key checking
1318  if ($force_utf8mb4_on_tables == 'confirmed') {
1319  $sql = 'SET FOREIGN_KEY_CHECKS=1';
1320  print '<!-- '.$sql.' -->';
1321  $resql = $db->query($sql);
1322  }
1323  } else {
1324  print '<tr><td colspan="2">Not available with database type '.$db->type.'</td></tr>';
1325  }
1326 }
1327 
1328 // rebuild sequences for pgsql
1329 if ($ok && GETPOST('rebuild_sequences', 'alpha')) {
1330  print '<tr><td colspan="2"><br>*** Force to rebuild sequences (for postgresql only)</td></tr>';
1331 
1332  if ($db->type == "pgsql") {
1333  $rebuild_sequence = GETPOST('rebuild_sequences', 'alpha');
1334 
1335  if ($rebuild_sequence == 'confirmed') {
1336  $sql = "SELECT dol_util_rebuild_sequences();";
1337  print '<!-- '.$sql.' -->';
1338  $resql = $db->query($sql);
1339  }
1340  } else {
1341  print '<tr><td colspan="2">Not available with database type '.$db->type.'</td></tr>';
1342  }
1343 }
1344 
1345 //
1346 if ($ok && GETPOST('repair_link_dispatch_lines_supplier_order_lines')) {
1347  /*
1348  * This script is meant to be run when upgrading from a dolibarr version < 3.8
1349  * to a newer version.
1350  *
1351  * Version 3.8 introduces a new column in llx_commande_fournisseur_dispatch, which
1352  * matches the dispatch to a specific supplier order line (so that if there are
1353  * several with the same product, the user can specifically tell which products of
1354  * which line were dispatched where).
1355  *
1356  * However when migrating, the new column has a default value of 0, which means that
1357  * old supplier orders whose lines were dispatched using the old dolibarr version
1358  * have unspecific dispatch lines, which are not taken into account by the new version,
1359  * thus making the order look like it was never dispatched at all.
1360  *
1361  * This scripts sets this foreign key to the first matching supplier order line whose
1362  * product (and supplier order of course) are the same as the dispatch’s.
1363  *
1364  * If the dispatched quantity is more than indicated on the order line (this happens if
1365  * there are several order lines for the same product), it creates new dispatch lines
1366  * pointing to the other order lines accordingly, until all the dispatched quantity is
1367  * accounted for.
1368  */
1369 
1370  $repair_link_dispatch_lines_supplier_order_lines = GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha');
1371 
1372 
1373  echo '<tr><th>Repair llx_commande_fournisseur_dispatch.fk_commandefourndet</th></tr>';
1374  echo '<tr><td>Repair in progress. This may take a while.</td></tr>';
1375 
1376  $sql_dispatch = 'SELECT * FROM '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch WHERE COALESCE(fk_commandefourndet, 0) = 0';
1377  $db->begin();
1378  $resql_dispatch = $db->query($sql_dispatch);
1379  $n_processed_rows = 0;
1380  $errors = array();
1381  if ($resql_dispatch) {
1382  if ($db->num_rows($resql_dispatch) == 0) {
1383  echo '<tr><td>Nothing to do.</td></tr>';
1384  exit;
1385  }
1386  while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
1387  $sql_line = 'SELECT line.rowid, line.qty FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet AS line';
1388  $sql_line .= ' WHERE line.fk_commande = '.((int) $obj_dispatch->fk_commande);
1389  $sql_line .= ' AND line.fk_product = '.((int) $obj_dispatch->fk_product);
1390  $resql_line = $db->query($sql_line);
1391 
1392  // s’il y a plusieurs lignes avec le même produit sur cette commande fournisseur,
1393  // on divise la ligne de dispatch en autant de lignes qu’on en a sur la commande pour le produit
1394  // et on met la quantité de la ligne dans la limite du "budget" indiqué par dispatch.qty
1395 
1396  $remaining_qty = $obj_dispatch->qty;
1397  $first_iteration = true;
1398  if (!$resql_line) {
1399  echo '<tr><td>Unable to find a matching supplier order line for dispatch #'.$obj_dispatch->rowid.'</td></tr>';
1400  $errors[] = $sql_line;
1401  $n_processed_rows++;
1402  continue;
1403  }
1404  if ($db->num_rows($resql_line) == 0) {
1405  continue;
1406  }
1407  while ($obj_line = $db->fetch_object($resql_line)) {
1408  if (!$remaining_qty) {
1409  break;
1410  }
1411  if (!$obj_line->rowid) {
1412  continue;
1413  }
1414  $qty_for_line = min($remaining_qty, $obj_line->qty);
1415  if ($first_iteration) {
1416  $sql_attach = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch';
1417  $sql_attach .= ' SET fk_commandefourndet = '.((int) $obj_line->rowid).', qty = '.((float) $qty_for_line);
1418  $sql_attach .= ' WHERE rowid = '.((int) $obj_dispatch->rowid);
1419  $first_iteration = false;
1420  } else {
1421  $sql_attach_values = array(
1422  ((int) $obj_dispatch->fk_commande),
1423  ((int) $obj_dispatch->fk_product),
1424  ((int) $obj_line->rowid),
1425  ((float) $qty_for_line),
1426  ((int) $obj_dispatch->fk_entrepot),
1427  ((int) $obj_dispatch->fk_user),
1428  $obj_dispatch->datec ? "'".$db->idate($db->jdate($obj_dispatch->datec))."'" : 'NULL',
1429  $obj_dispatch->comment ? "'".$db->escape($obj_dispatch->comment)."'" : 'NULL',
1430  $obj_dispatch->status ? ((int) $obj_dispatch->status) : 'NULL',
1431  $obj_dispatch->tms ? "'".$db->idate($db->jdate($obj_dispatch->tms))."'" : 'NULL',
1432  $obj_dispatch->batch ? "'".$db->escape($obj_dispatch->batch)."'" : 'NULL',
1433  $obj_dispatch->eatby ? "'".$db->escape($obj_dispatch->eatby)."'" : 'NULL',
1434  $obj_dispatch->sellby ? "'".$db->escape($obj_dispatch->sellby)."'" : 'NULL'
1435  );
1436  $sql_attach_values = join(', ', $sql_attach_values);
1437 
1438  $sql_attach = 'INSERT INTO '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch';
1439  $sql_attach .= ' (fk_commande, fk_product, fk_commandefourndet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)';
1440  $sql_attach .= " VALUES (".$sql_attach_values.")";
1441  }
1442 
1443  if ($repair_link_dispatch_lines_supplier_order_lines == 'confirmed') {
1444  $resql_attach = $db->query($sql_attach);
1445  } else {
1446  $resql_attach = true; // Force success in test mode
1447  }
1448 
1449  if ($resql_attach) {
1450  $remaining_qty -= $qty_for_line;
1451  } else {
1452  $errors[] = $sql_attach;
1453  }
1454 
1455  $first_iteration = false;
1456  }
1457  $n_processed_rows++;
1458 
1459  // report progress every 256th row
1460  if (!($n_processed_rows & 0xff)) {
1461  echo '<tr><td>Processed '.$n_processed_rows.' rows with '.count($errors).' errors…'."</td></tr>\n";
1462  flush();
1463  ob_flush();
1464  }
1465  }
1466  } else {
1467  echo '<tr><td>Unable to find any dispatch without an fk_commandefourndet.'."</td></tr>\n";
1468  echo $sql_dispatch."\n";
1469  }
1470  echo '<tr><td>Fixed '.$n_processed_rows.' rows with '.count($errors).' errors…'."</td></tr>\n";
1471  echo '<tr><td>DONE.'."</td></tr>\n";
1472 
1473  if (count($errors)) {
1474  $db->rollback();
1475  echo '<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
1476  } else {
1477  $db->commit();
1478  }
1479  $db->close();
1480 
1481  echo '<tr><td><h3>SQL queries with errors:</h3></tr></td>';
1482  echo '<tr><td>'.join('</td></tr><tr><td>', $errors).'</td></tr>';
1483 }
1484 
1485 print '</table>';
1486 
1487 
1488 
1489 if (empty($actiondone)) {
1490  print '<div class="error">'.$langs->trans("ErrorWrongParameters").'</div>';
1491 }
1492 
1493 if ($oneoptionset) {
1494  print '<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(GETPOSTISSET("login") ? '&username='.urlencode(GETPOST("login")) : '').'">';
1495  print $langs->trans("GoToDolibarr");
1496  print '</a></div>';
1497 } else {
1498  print '<div class="center warning" style="padding-top: 10px">';
1499  print $langs->trans("SetAtLeastOneOptionAsUrlParameter");
1500  print '</div>';
1501 }
1502 
1503 dolibarr_install_syslog("--- repair: end");
1504 pFooter(1, $setuplang);
1505 
1506 if ($db->connected) {
1507  $db->close();
1508 }
1509 
1510 // Return code if ran from command line
1511 if (!$ok && isset($argv[1])) {
1512  exit(1);
1513 }
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:712
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:1250
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
Definition: files.lib.php:1376
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:480
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:485
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
Definition: images.lib.php:58
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
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
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.