30include_once
'inc.php';
31if (file_exists($conffile)) {
32 include_once $conffile;
34require_once $dolibarr_main_document_root.
'/core/lib/admin.lib.php';
35include_once $dolibarr_main_document_root.
'/core/lib/images.lib.php';
36require_once $dolibarr_main_document_root.
'/core/class/extrafields.class.php';
37require_once
'lib/repair.lib.php';
45$err = error_reporting();
50$setuplang =
GETPOST(
"selectlang",
'aZ09', 3) ?
GETPOST(
"selectlang",
'aZ09', 3) :
'auto';
51$langs->setDefaultLang($setuplang);
53$langs->loadLangs(array(
"admin",
"install",
"other"));
55if ($dolibarr_main_db_type ==
"mysqli") {
58if ($dolibarr_main_db_type ==
"pgsql") {
61if ($dolibarr_main_db_type ==
"mssql") {
67if (!is_object($conf)) {
81print
'<h3>'.$langs->trans(
"Repair").
'</h3>';
83print
'<div class="warning" style="padding-top: 10px">';
84print $langs->trans(
"SetAtLeastOneOptionAsUrlParameter");
91print
'Option standard is '.(GETPOST(
'standard',
'alpha') ?
GETPOST(
'standard',
'alpha') :
'undefined').
'<br>'.
"\n";
93print
'Option force_disable_of_modules_not_found is '.(GETPOST(
'force_disable_of_modules_not_found',
'alpha') ?
GETPOST(
'force_disable_of_modules_not_found',
'alpha') :
'undefined').
'<br>'.
"\n";
95print
'Option restore_thirdparties_logos is '.(GETPOST(
'restore_thirdparties_logos',
'alpha') ?
GETPOST(
'restore_thirdparties_logos',
'alpha') :
'undefined').
'<br>'.
"\n";
96print
'Option restore_user_pictures is '.(GETPOST(
'restore_user_pictures',
'alpha') ?
GETPOST(
'restore_user_pictures',
'alpha') :
'undefined').
'<br>'.
"\n";
97print
'Option rebuild_product_thumbs is '.(GETPOST(
'rebuild_product_thumbs',
'alpha') ?
GETPOST(
'rebuild_product_thumbs',
'alpha') :
'undefined').
'<br>'.
"\n";
99print
'Option clean_linked_elements is '.(GETPOST(
'clean_linked_elements',
'alpha') ?
GETPOST(
'clean_linked_elements',
'alpha') :
'undefined').
'<br>'.
"\n";
100print
'Option clean_menus is '.(GETPOST(
'clean_menus',
'alpha') ?
GETPOST(
'clean_menus',
'alpha') :
'undefined').
'<br>'.
"\n";
101print
'Option clean_orphelin_dir is '.(GETPOST(
'clean_orphelin_dir',
'alpha') ?
GETPOST(
'clean_orphelin_dir',
'alpha') :
'undefined').
'<br>'.
"\n";
102print
'Option clean_product_stock_batch is '.(GETPOST(
'clean_product_stock_batch',
'alpha') ?
GETPOST(
'clean_product_stock_batch',
'alpha') :
'undefined').
'<br>'.
"\n";
103print
'Option clean_perm_table is '.(GETPOST(
'clean_perm_table',
'alpha') ?
GETPOST(
'clean_perm_table',
'alpha') :
'undefined').
'<br>'.
"\n";
104print
'Option repair_link_dispatch_lines_supplier_order_lines, is '.(GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha') ?
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha') :
'undefined').
'<br>'.
"\n";
106print
'Option set_empty_time_spent_amount is '.(GETPOST(
'set_empty_time_spent_amount',
'alpha') ?
GETPOST(
'set_empty_time_spent_amount',
'alpha') :
'undefined').
'<br>'.
"\n";
108print
'Option force_utf8_on_tables (force utf8 + row=dynamic), for mysql/mariadb only, is '.(GETPOST(
'force_utf8_on_tables',
'alpha') ?
GETPOST(
'force_utf8_on_tables',
'alpha') :
'undefined').
'<br>'.
"\n";
109print
'<span class="valignmiddle">'.
"Option force_utf8mb4_on_tables (force utf8mb4 + row=dynamic, EXPERIMENTAL!), for mysql/mariadb only, is ".(
GETPOST(
'force_utf8mb4_on_tables',
'alpha') ?
GETPOST(
'force_utf8mb4_on_tables',
'alpha') :
'undefined');
111if ($dolibarr_main_db_character_set !=
'utf8mb4') {
112 print
'<img src="../theme/eldy/img/warning.png" class="pictofortooltip valignmiddle" title="If you switch to utf8mb4, you must also check the value for $dolibarr_main_db_character_set and $dolibarr_main_db_collation into conf/conf.php file.">';
115print
"Option force_collation_from_conf_on_tables (force ".$conf->db->character_set.
"/".$conf->db->dolibarr_main_db_collation.
" + row=dynamic), for mysql/mariadb only is ".(
GETPOST(
'force_collation_from_conf_on_tables',
'alpha') ?
GETPOST(
'force_collation_from_conf_on_tables',
'alpha') :
'undefined').
"<br>\n";
118print
'Option rebuild_sequences, for postgresql only, is '.(GETPOST(
'rebuild_sequences',
'alpha') ?
GETPOST(
'rebuild_sequences',
'alpha') :
'undefined').
'<br>'.
"\n";
123print
'<table cellspacing="0" cellpadding="1" class="centpercent">';
127if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass) || !empty($dolibarr_main_db_encrypted_pass)) {
128 require_once $dolibarr_main_document_root.
'/core/lib/security.lib.php';
129 if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass)) {
130 $dolibarr_main_db_pass = preg_replace(
'/crypted:/i',
'', $dolibarr_main_db_pass);
131 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_pass);
132 $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass;
134 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_encrypted_pass);
139$conf->db->type = $dolibarr_main_db_type;
140$conf->db->host = $dolibarr_main_db_host;
141$conf->db->port = $dolibarr_main_db_port;
142$conf->db->name = $dolibarr_main_db_name;
143$conf->db->user = $dolibarr_main_db_user;
144$conf->db->pass = $dolibarr_main_db_pass;
147$conf->db->dolibarr_main_db_encryption = isset($dolibarr_main_db_encryption) ? $dolibarr_main_db_encryption : 0;
148$conf->db->dolibarr_main_db_cryptkey = isset($dolibarr_main_db_cryptkey) ? $dolibarr_main_db_cryptkey :
'';
150$db =
getDoliDBInstance($conf->db->type, $conf->db->host, $conf->db->user, $conf->db->pass, $conf->db->name, (
int) $conf->db->port);
153 print
'<tr><td class="nowrap">';
154 print $langs->trans(
"ServerConnection").
" : $dolibarr_main_db_host</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
155 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ServerConnection").
": ".$dolibarr_main_db_host.$langs->transnoentities(
"OK"));
158 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->transnoentities(
"Error").
"</td></tr>";
159 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
164 if ($db->database_selected) {
165 print
'<tr><td class="nowrap">';
166 print $langs->trans(
"DatabaseConnection").
" : ".$dolibarr_main_db_name.
"</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
170 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->trans(
"Error").
"</td></tr>";
171 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
178 $version = $db->getVersion();
179 $versionarray = $db->getVersionArray();
180 print
'<tr><td>'.$langs->trans(
"ServerVersion").
'</td>';
181 print
'<td class="right">'.$version.
'</td></tr>';
186$conf->setValues($db);
188if (defined(
'SYSLOG_FILE')) {
189 $conf->global->SYSLOG_FILE = constant(
'SYSLOG_FILE');
191$conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
196$oneoptionset = (
GETPOST(
'standard',
'alpha') ||
GETPOST(
'restore_thirdparties_logos',
'alpha') ||
GETPOST(
'clean_linked_elements',
'alpha') ||
GETPOST(
'clean_menus',
'alpha')
197 ||
GETPOST(
'clean_orphelin_dir',
'alpha') ||
GETPOST(
'clean_product_stock_batch',
'alpha') ||
GETPOST(
'set_empty_time_spent_amount',
'alpha') ||
GETPOST(
'rebuild_product_thumbs',
'alpha')
198 ||
GETPOST(
'clean_perm_table',
'alpha')
199 ||
GETPOST(
'force_disable_of_modules_not_found',
'alpha')
200 ||
GETPOST(
'force_utf8_on_tables',
'alpha') ||
GETPOST(
'force_utf8mb4_on_tables',
'alpha') ||
GETPOST(
'force_collation_from_conf_on_tables',
'alpha')
201 ||
GETPOST(
'rebuild_sequences',
'alpha') ||
GETPOST(
'recalculateinvoicetotal',
'alpha'));
203if ($ok && $oneoptionset) {
205 print
'<tr><td colspan="2">'.$langs->trans(
"PleaseBePatient").
'<br><br></td></tr>';
211if ($ok &&
GETPOST(
'standard',
'alpha')) {
212 $dir =
"mysql/migration/";
219 $filesindir = array();
220 $handle = opendir($dir);
221 if (is_resource($handle)) {
222 while (($file = readdir($handle)) !==
false) {
223 if (preg_match(
'/\.sql$/i', $file)) {
224 $filesindir[] = $file;
230 foreach ($filesindir as $file) {
231 if (preg_match(
'/repair/i', $file)) {
237 foreach ($filelist as $file) {
238 print
'<tr><td class="nowrap">*** ';
239 print $langs->trans(
"Script").
'</td><td class="right">'.$file.
'</td></tr>';
241 $name = substr($file, 0,
dol_strlen($file) - 4);
244 $ok =
run_sql($dir.$file, 0,
'', 1);
251if ($ok &&
GETPOST(
'standard',
'alpha')) {
255 $listofmodulesextra = array(
'societe' =>
'societe',
'adherent' =>
'adherent',
'product' =>
'product',
256 'socpeople' =>
'socpeople',
'propal' =>
'propal',
'commande' =>
'commande',
257 'facture' =>
'facture',
'facturedet' =>
'facturedet',
'facture_rec' =>
'facture_rec',
'facturedet_rec' =>
'facturedet_rec',
258 'supplier_proposal' =>
'supplier_proposal',
'commande_fournisseur' =>
'commande_fournisseur',
259 'facture_fourn' =>
'facture_fourn',
'facture_fourn_rec' =>
'facture_fourn_rec',
'facture_fourn_det' =>
'facture_fourn_det',
'facture_fourn_det_rec' =>
'facture_fourn_det_rec',
260 'fichinter' =>
'fichinter',
'fichinterdet' =>
'fichinterdet',
261 'inventory' =>
'inventory',
262 'actioncomm' =>
'actioncomm',
'bom_bom' =>
'bom_bom',
'mrp_mo' =>
'mrp_mo',
263 'adherent_type' =>
'adherent_type',
'user' =>
'user',
'partnership' =>
'partnership',
'projet' =>
'projet',
'projet_task' =>
'projet_task',
'ticket' =>
'ticket');
266 print
'<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
267 foreach ($listofmodulesextra as $tablename => $elementtype) {
269 $tableextra = MAIN_DB_PREFIX.$tablename.
'_extrafields';
272 $arrayoffieldsdesc = $extrafields->fetch_name_optionals_label($elementtype);
275 $arrayoffieldsfound = array();
276 $resql = $db->DDLDescTable($tableextra);
278 print
'<tr><td>Check availability of extra field for '.$tableextra;
280 while ($obj = $db->fetch_object($resql)) {
281 $fieldname = $fieldtype =
'';
282 if (preg_match(
'/mysql/', $db->type)) {
283 $fieldname = $obj->Field;
284 $fieldtype = $obj->Type;
286 $fieldname = isset($obj->Key) ? $obj->Key : $obj->attname;
287 $fieldtype = isset($obj->Type) ? $obj->Type :
'varchar';
290 if (empty($fieldname)) {
293 if (in_array($fieldname, array(
'rowid',
'tms',
'fk_object',
'import_key'))) {
296 $arrayoffieldsfound[$fieldname] = array(
'type' => $fieldtype);
298 print
' - Found '.count($arrayoffieldsfound).
' fields into table';
299 if (count($arrayoffieldsfound) > 0) {
300 print
' <span class="opacitymedium">('.implode(
', ', array_keys($arrayoffieldsfound)).
')</span>';
305 foreach ($arrayoffieldsdesc as $code => $label) {
306 if (!in_array($code, array_keys($arrayoffieldsfound))) {
307 print
'Found field '.$code.
' declared into '.MAIN_DB_PREFIX.
'extrafields table but not found into desc of table '.$tableextra.
" -> ";
308 $type = $extrafields->attributes[$elementtype][
'type'][$code];
309 $length = $extrafields->attributes[$elementtype][
'size'][$code];
315 if ($type ==
'boolean') {
318 } elseif ($type ==
'price') {
321 } elseif ($type ==
'phone') {
324 } elseif ($type ==
'mail') {
327 } elseif (($type ==
'select') || ($type ==
'sellist') || ($type ==
'radio') || ($type ==
'checkbox') || ($type ==
'chkbxlst')) {
330 } elseif ($type ==
'link') {
340 'value' => $lengthdb,
341 'attribute' => $attribute,
342 'default' => $default,
349 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
350 $result = $db->DDLAddField($tableextra, $code, $field_desc,
"");
353 print
"KO ".$db->lasterror.
"<br>\n";
358 print
' - Mode test, no column added.';
363 print
"</td><td> </td></tr>\n";
365 print
'<tr><td>Table '.$tableextra.
' is not found</td><td></td></tr>'.
"\n";
372if ($ok &&
GETPOST(
'standard',
'alpha')) {
378if ($ok &&
GETPOST(
'standard',
'alpha')) {
379 print
'<tr><td colspan="2"><br>*** Clean constant record of modules not enabled</td></tr>';
381 $sql =
"SELECT name, entity, value";
382 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
383 $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'";
384 $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'";
385 $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_%'";
386 $sql .=
" OR name LIKE 'MAIN_MODULE_%_MODULEFOREXTERNAL'";
387 $sql .=
" ORDER BY name, entity";
389 $resql = $db->query($sql);
391 $num = $db->num_rows($resql);
398 $obj = $db->fetch_object($resql);
401 if (preg_match(
'/MAIN_MODULE_([^_]+)_(.+)/i', $obj->name, $reg)) {
405 $sql2 =
"SELECT COUNT(*) as nb";
406 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
407 $sql2 .=
" WHERE name = 'MAIN_MODULE_".$name.
"'";
408 $sql2 .=
" AND entity = ".((int) $obj->entity);
409 $resql2 = $db->query($sql2);
411 $obj2 = $db->fetch_object($resql2);
412 if ($obj2 && $obj2->nb == 0) {
414 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = '".$db->escape($obj->name).
"' AND entity = ".((int) $obj->entity);
416 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
417 $db->query($sqldelete);
419 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>';
421 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>';
441if ($ok &&
GETPOST(
'standard',
'alpha')) {
442 print
'<tr><td colspan="2"><br>*** Clean definition of boxes of modules not enabled</td></tr>';
444 $sql =
"SELECT file, entity FROM ".MAIN_DB_PREFIX.
"boxes_def";
445 $sql .=
" WHERE file like '%@%'";
447 $resql = $db->query($sql);
449 $num = $db->num_rows($resql);
456 $obj = $db->fetch_object($resql);
459 if (preg_match(
'/^(.+)@(.+)$/i', $obj->file, $reg)) {
463 $sql2 =
"SELECT COUNT(*) as nb";
464 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
465 $sql2 .=
" WHERE name = 'MAIN_MODULE_".strtoupper($module).
"'";
466 $sql2 .=
" AND entity = ".((int) $obj->entity);
467 $sql2 .=
" AND value <> 0";
468 $resql2 = $db->query($sql2);
470 $obj2 = $db->fetch_object($resql2);
471 if ($obj2 && $obj2->nb == 0) {
473 $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).
")";
474 $sqldeleteb =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def WHERE file = '".$db->escape($obj->file).
"' AND entity = ".((int) $obj->entity);
476 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
477 $db->query($sqldeletea);
478 $db->query($sqldeleteb);
480 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>';
482 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>';
500if ($ok &&
GETPOST(
'restore_thirdparties_logos')) {
505 print
'<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
507 $sql =
"SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX.
"societe as s ORDER BY s.nom";
508 $resql = $db->query($sql);
510 $num = $db->num_rows($resql);
514 $obj = $db->fetch_object($resql);
522 $tmp = explode(
'.', $obj->logo);
524 if (isset($tmp[1])) {
529 $filetotest = $dolibarr_main_data_root.
'/societe/logos/'.$name.$ext;
530 $filetotestsmall = $dolibarr_main_data_root.
'/societe/logos/thumbs/'.$name.
'_small'.$ext;
532 print
'Check thirdparty '.$obj->rowid.
' name='.$obj->name.
' logo='.$obj->logo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
534 $filetarget = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/'.$name.$ext;
535 $filetargetsmall = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs/'.$name.
'_small'.$ext;
538 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
539 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos');
542 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
543 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
544 dol_copy($filetotest, $filetarget,
'', 0);
550 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
551 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs');
553 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
554 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
555 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
574if ($ok &&
GETPOST(
'restore_user_pictures',
'alpha')) {
579 print
'<tr><td colspan="2"><br>*** Restore user pictures<br>';
581 $sql =
"SELECT s.rowid, s.firstname, s.lastname, s.login, s.photo FROM ".MAIN_DB_PREFIX.
"user as s ORDER BY s.rowid";
582 $resql = $db->query($sql);
584 $num = $db->num_rows($resql);
588 $obj = $db->fetch_object($resql);
596 $tmp = explode(
'.', $obj->photo);
598 if (isset($tmp[1])) {
603 $filetotest = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/'.$name.$ext;
604 $filetotestsmall = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_small'.$ext;
605 $filetotestmini = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_mini'.$ext;
607 print
'Check user '.$obj->rowid.
' lastname='.$obj->lastname.
' firstname='.$obj->firstname.
' photo='.$obj->photo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
609 $filetarget = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/'.$name.$ext;
610 $filetargetsmall = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_small'.$ext;
611 $filetargetmini = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_mini'.$ext;
615 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
616 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid);
619 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
620 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
621 dol_copy($filetotest, $filetarget,
'', 0);
627 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
628 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
631 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
632 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
633 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
639 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
640 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
643 print
" -> Copy file ".$filetotestmini.
" -> ".$filetargetmini.
"<br>\n";
644 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
645 dol_copy($filetotestmini, $filetargetmini,
'', 0);
663if ($ok &&
GETPOST(
'rebuild_product_thumbs',
'alpha')) {
665 global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
667 print
'<tr><td colspan="2"><br>*** Rebuild product thumbs<br>';
669 $sql =
"SELECT s.rowid, s.ref FROM ".MAIN_DB_PREFIX.
"product as s ORDER BY s.ref";
670 $resql = $db->query($sql);
672 $num = $db->num_rows($resql);
676 $obj = $db->fetch_object($resql);
678 if (!empty($obj->ref)) {
679 $files =
dol_dir_list($dolibarr_main_data_root.
'/produit/'.$obj->ref,
'files', 0);
680 foreach ($files as $file) {
683 $imgThumbSmall =
'notbuild';
684 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
686 $imgThumbSmall =
vignette($file[
'fullname'], $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
688 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbSmall.
" maxwidthsmall=".$maxwidthsmall.
" maxheightsmall=".$maxheightsmall.
"<br>\n";
689 $imgThumbMini =
'notbuild';
690 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
693 $imgThumbMini =
vignette($file[
'fullname'], $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
695 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbMini.
" maxwidthmini=".$maxwidthmini.
" maxheightmini=".$maxheightmini.
"<br>\n";
711if ($ok &&
GETPOST(
'clean_linked_elements',
'alpha')) {
712 print
'<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
714 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'commande').
"</td></tr>\n";
717 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'facture').
"</td></tr>\n";
720 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'facture').
"</td></tr>\n";
723 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'shipping').
"</td></tr>\n";
726 print
'<tr><td colspan="2">'.checkLinkedElements(
'shipping',
'delivery').
"</td></tr>\n";
729 print
'<tr><td colspan="2">'.checkLinkedElements(
'order_supplier',
'invoice_supplier').
"</td></tr>\n";
734if ($ok &&
GETPOST(
'clean_menus',
'alpha')) {
735 print
'<tr><td colspan="2"><br>*** Clean menu entries coming from disabled modules</td></tr>';
737 $sql =
"SELECT rowid, module";
738 $sql .=
" FROM ".MAIN_DB_PREFIX.
"menu as c";
739 $sql .=
" WHERE module IS NOT NULL AND module <> ''";
740 $sql .=
" ORDER BY module";
742 $resql = $db->query($sql);
744 $num = $db->num_rows($resql);
748 $obj = $db->fetch_object($resql);
750 $modulecond = $obj->module;
751 $modulecondarray = explode(
'|', $obj->module);
760 foreach ($modulecondarray as $tmpname) {
761 if ($tmpname ==
'margins') {
766 if (!empty($conf->$tmpname)) {
767 $result = $conf->$tmpname->enabled;
774 if (!$moduleok && $modulecond) {
775 print
' - Module condition '.$modulecond.
' seems ko, we delete menu entry.';
776 if (
GETPOST(
'clean_menus') ==
'confirmed') {
777 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"menu WHERE module = '".$db->escape($modulecond).
"'";
778 $resql2 = $db->query($sql2);
783 print
' - <span class="warning">Cleaned</span>';
786 print
' - <span class="warning">Canceled (test mode)</span>';
789 print
' - Module condition '.$modulecond.
' is ok, we do nothing.';
808 print
'<tr><td>No menu entries of disabled menus found</td></tr>';
818if ($ok &&
GETPOST(
'clean_orphelin_dir',
'alpha')) {
819 $listmodulepart = array(
'company',
'invoice',
'invoice_supplier',
'propal',
'order',
'order_supplier',
'contract',
'tax');
820 foreach ($listmodulepart as $modulepart) {
821 $filearray = array();
822 $upload_dir = isset($conf->$modulepart->dir_output) ? $conf->$modulepart->dir_output :
'';
823 if ($modulepart ==
'company') {
824 $upload_dir = $conf->societe->dir_output;
826 if ($modulepart ==
'invoice') {
827 $upload_dir = $conf->facture->dir_output;
829 if ($modulepart ==
'invoice_supplier') {
830 $upload_dir = $conf->fournisseur->facture->dir_output;
832 if ($modulepart ==
'order') {
833 $upload_dir = $conf->commande->dir_output;
835 if ($modulepart ==
'order_supplier') {
836 $upload_dir = $conf->fournisseur->commande->dir_output;
838 if ($modulepart ==
'contract') {
839 $upload_dir = $conf->contrat->dir_output;
842 if (empty($upload_dir)) {
846 print
'<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.
'</td></tr>';
848 $filearray =
dol_dir_list($upload_dir,
"files", 1,
'', array(
'^SPECIMEN\.pdf$',
'^\.',
'(\.meta|_preview.*\.png)$',
'^temp$',
'^payments$',
'^CVS$',
'^thumbs$'),
'', SORT_DESC, 1,
true);
851 if ($modulepart ==
'company') {
852 include_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
853 $object_instance =
new Societe($db);
855 if ($modulepart ==
'invoice') {
856 include_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
857 $object_instance =
new Facture($db);
858 } elseif ($modulepart ==
'invoice_supplier') {
859 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.facture.class.php';
861 } elseif ($modulepart ==
'propal') {
862 include_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
863 $object_instance =
new Propal($db);
864 } elseif ($modulepart ==
'order') {
865 include_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
866 $object_instance =
new Commande($db);
867 } elseif ($modulepart ==
'order_supplier') {
868 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
870 } elseif ($modulepart ==
'contract') {
871 include_once DOL_DOCUMENT_ROOT.
'/contrat/class/contrat.class.php';
872 $object_instance =
new Contrat($db);
873 } elseif ($modulepart ==
'tax') {
874 include_once DOL_DOCUMENT_ROOT.
'/compta/sociales/class/chargesociales.class.php';
878 foreach ($filearray as $key => $file) {
879 if (!is_dir($file[
'name'])
880 && $file[
'name'] !=
'.'
881 && $file[
'name'] !=
'..'
882 && $file[
'name'] !=
'CVS'
885 $relativefile = preg_replace(
'/'.preg_quote($upload_dir.
'/',
'/').
'/',
'', $file[
'fullname']);
890 $object_instance->id = 0;
891 $object_instance->ref =
'';
895 if ($modulepart ==
'invoice') {
896 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
899 if ($modulepart ==
'invoice_supplier') {
900 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg);
901 $id = empty($reg[1]) ?
'' : $reg[1];
903 if ($modulepart ==
'propal') {
904 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
907 if ($modulepart ==
'order') {
908 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
911 if ($modulepart ==
'order_supplier') {
912 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
915 if ($modulepart ==
'contract') {
916 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
919 if ($modulepart ==
'tax') {
920 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg);
926 $result = $object_instance->fetch($id, $ref);
930 print
'<tr><td colspan="2">';
931 print
'Delete orphelins file '.$file[
'fullname'].
'<br>';
932 if (
GETPOST(
'clean_orphelin_dir',
'alpha') ==
'confirmed') {
937 } elseif ($result < 0) {
938 print
'Error in '.get_class($object_instance).
'.fetch of id'.$id.
' ref='.$ref.
', result='.$result.
'<br>';
947if ($ok &&
GETPOST(
'clean_product_stock_batch',
'alpha')) {
948 $methodtofix =
GETPOST(
'methodtofix',
'alpha') ?
GETPOST(
'methodtofix',
'alpha') :
'updatestock';
950 print
'<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
952 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
953 $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";
954 $sql .=
" WHERE p.rowid = ps.fk_product";
955 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
956 $sql .=
" HAVING (SUM(pb.qty) IS NOT NULL AND reel != SUM(pb.qty)) OR (SUM(pb.qty) IS NULL AND p.tobatch > 0)";
958 $resql = $db->query($sql);
960 $num = $db->num_rows($resql);
965 $obj = $db->fetch_object($resql);
966 print
'<tr><td>Product '.$obj->rowid.
'-'.$obj->ref.
' in warehouse id='.$obj->fk_entrepot.
' (product_stock.id='.$obj->psrowid.
'): '.$obj->reel.
' (Stock product_stock.reel) != '.($obj->reelbatch ? $obj->reelbatch :
'0').
' (Stock batch sum product_batch)';
969 if ($obj->reel != $obj->reelbatch) {
970 if (empty($obj->tobatch)) {
972 print
' -> Delete qty '.$obj->reelbatch.
' for any lot linked to fk_product_stock='.$obj->psrowid;
973 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_batch";
974 $sql2 .=
" WHERE fk_product_stock = ".((int) $obj->psrowid);
977 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
978 $resql2 = $db->query($sql2);
985 if ($methodtofix ==
'updatebatch') {
987 print
' -> Insert qty '.($obj->reel - $obj->reelbatch).
' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
988 $sql2 =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_batch(fk_product_stock, batch, qty)";
989 $sql2 .=
"VALUES(".((int) $obj->psrowid).
", '000000', ".((float) ($obj->reel - $obj->reelbatch)).
")";
992 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
993 $resql2 = $db->query($sql2);
1002 if ($methodtofix ==
'updatestock') {
1004 print
' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((float) $obj->reelbatch) :
'0').
' for ps.rowid = '.((
int) $obj->psrowid);
1005 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"product_stock";
1006 $sql2 .=
" SET reel = ".($obj->reelbatch ? ((float) $obj->reelbatch) :
'0').
" WHERE rowid = ".((
int) $obj->psrowid);
1009 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
1014 $resql2 = $db->query($sql2);
1017 $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)';
1018 $resql3 = $db->query($sql3);
1043 print
'<tr><td colspan="2">Nothing to do</td></tr>';
1052if ($ok &&
GETPOST(
'clean_product_stock_negative_if_batch',
'alpha')) {
1053 print
'<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
1055 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
1056 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product as p, ".MAIN_DB_PREFIX.
"product_stock as ps, ".MAIN_DB_PREFIX.
"product_batch as pb";
1057 $sql .=
" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
1058 $sql .=
" AND p.tobatch > 0";
1059 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
1060 $sql .=
" HAVING reel != SUM(pb.qty)";
1061 $resql = $db->query($sql);
1063 $num = $db->num_rows($resql);
1068 $obj = $db->fetch_object($resql);
1069 print
'<tr><td>'.$obj->rowid.
'-'.$obj->ref.
'-'.$obj->fk_entrepot.
' -> '.$obj->psrowid.
': '.$obj->reel.
' != '.$obj->reelbatch;
1078if ($ok &&
GETPOST(
'set_empty_time_spent_amount',
'alpha')) {
1079 print
'<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
1081 $sql =
"SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
1082 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"user as u";
1083 $sql .=
" WHERE ptt.fk_user = u.rowid";
1084 $sql .=
" AND ptt.thm IS NULL and u.thm > 0";
1085 $sql .=
" GROUP BY u.rowid, u.login, u.thm";
1087 $resql = $db->query($sql);
1089 $num = $db->num_rows($resql);
1094 $obj = $db->fetch_object($resql);
1095 print
'<tr><td>'.$obj->login.
'-'.$obj->user_id.
' ('.$obj->nb.
' lines to fix) -> '.$obj->user_thm;
1099 if (
GETPOST(
'set_empty_time_spent_amount') ==
'confirmed') {
1100 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"element_time";
1101 $sql2 .=
" SET thm = ".$obj->user_thm.
" WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id);
1102 $resql2 = $db->query($sql2);
1124 print
'<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
1133if ($ok &&
GETPOST(
'force_disable_of_modules_not_found',
'alpha')) {
1134 print
'<tr><td colspan="2"><br>*** Force modules not found physically to be disabled (only modules adding js, css or hooks can be detected as removed physically)</td></tr>';
1136 $arraylistofkey = array(
'hooks',
'js',
'css');
1138 foreach ($arraylistofkey as $key) {
1139 $sql =
"SELECT DISTINCT name, value";
1140 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
1141 $sql .=
" WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($key).
"'";
1142 $sql .=
" ORDER BY name";
1144 $resql = $db->query($sql);
1146 $num = $db->num_rows($resql);
1150 $obj = $db->fetch_object($resql);
1151 $constantname = $obj->name;
1159 if (preg_match(
'/MAIN_MODULE_(.*)_'.strtoupper($key).
'/i', $constantname, $reg)) {
1160 $name = strtolower($reg[1]);
1166 if ($key ==
'hooks') {
1167 $reloffile = $name.
'/class/actions_'.$name.
'.class.php';
1170 $value = $obj->value;
1171 $valuearray = (array) json_decode($value);
1172 $reloffile = $valuearray[0];
1173 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1175 if ($key ==
'css') {
1176 $value = $obj->value;
1177 $valuearray = (array) json_decode($value);
1178 if ($value && (!is_array($valuearray) || count($valuearray) == 0)) {
1179 $valuearray = array();
1180 $valuearray[0] = $value;
1182 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1197 print
' - File of '.$key.
' ('.$reloffile.
') NOT found, we disable the module.';
1198 if (
GETPOST(
'force_disable_of_modules_not_found') ==
'confirmed') {
1199 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"_".strtoupper($key).
"'";
1200 $resql2 = $db->query($sql2);
1205 $sql3 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"'";
1206 $resql3 = $db->query($sql3);
1211 print
' - <span class="warning">Cleaned</span>';
1214 print
' - <span class="warning">Canceled (test mode)</span>';
1217 print
' - File of '.$key.
' ('.$reloffile.
') found, we do nothing.';
1237 print
'<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).
'</td></tr>';
1247if ($ok &&
GETPOST(
'clean_perm_table',
'alpha')) {
1248 print
'<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1251 foreach ($conf->modules as $key => $val) {
1252 $listofmods .= ($listofmods ?
',' :
'').
"'".$db->escape($val).
"'";
1255 $sql =
"SELECT id, libelle as label, module from ".MAIN_DB_PREFIX.
"rights_def WHERE module NOT IN (".$db->sanitize($listofmods, 1).
") AND id > 100000";
1257 $resql = $db->query($sql);
1259 $num = $db->num_rows($resql);
1263 $obj = $db->fetch_object($resql);
1265 print
'<tr><td>Found line with id '.$obj->id.
', label "'.$obj->label.
'" of module "'.$obj->module.
'" to delete';
1266 if (
GETPOST(
'clean_perm_table',
'alpha') ==
'confirmed') {
1267 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def WHERE id = ".((int) $obj->id);
1268 $resqldelete = $db->query($sqldelete);
1269 if (!$resqldelete) {
1279 print
'<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1289if ($ok &&
GETPOST(
'force_utf8_on_tables',
'alpha')) {
1290 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>';
1292 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1293 $force_utf8_on_tables =
GETPOST(
'force_utf8_on_tables',
'alpha');
1295 $listoftables = $db->DDLListTablesFull($db->database_name);
1298 if ($force_utf8_on_tables ==
'confirmed') {
1299 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1300 print
'<!-- '.$sql.
' -->';
1301 $resql = $db->query($sql);
1304 foreach ($listoftables as $table) {
1306 if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1309 if ($table[1] ==
'VIEW') {
1310 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' (Skipped)</td></tr>';
1314 print
'<tr><td colspan="2">';
1316 $sql1 =
"ALTER TABLE ".$table[0].
" ROW_FORMAT=dynamic";
1317 $sql2 =
"ALTER TABLE ".$table[0].
" CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci";
1318 print
'<!-- '.$sql1.
' -->';
1319 print
'<!-- '.$sql2.
' -->';
1320 if ($force_utf8_on_tables ==
'confirmed') {
1321 $resql1 = $db->query($sql1);
1323 $resql2 = $db->query($sql2);
1327 print
' - Done ('.(($resql1 && $resql2) ?
'OK' :
'KO').
')';
1329 print
' - Disabled';
1335 if ($force_utf8_on_tables ==
'confirmed') {
1336 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1337 print
'<!-- '.$sql.
' -->';
1338 $resql = $db->query($sql);
1341 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1346if ($ok &&
GETPOST(
'force_utf8mb4_on_tables',
'alpha')) {
1347 print
'<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8mb4/utf8mb4_unicode_ci (for mysql/mariadb only)</td></tr>';
1349 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1350 $force_utf8mb4_on_tables =
GETPOST(
'force_utf8mb4_on_tables',
'alpha');
1352 $listoftables = $db->DDLListTablesFull($db->database_name);
1355 if ($force_utf8mb4_on_tables ==
'confirmed') {
1356 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1357 print
'<!-- '.$sql.
' -->';
1358 $resql = $db->query($sql);
1361 foreach ($listoftables as $table) {
1363 if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1366 if ($table[1] ==
'VIEW') {
1367 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' (Skipped)</td></tr>';
1371 print
'<tr><td colspan="2">';
1373 $sql1 =
"ALTER TABLE ".$table[0].
" ROW_FORMAT=dynamic";
1374 $sql2 =
"ALTER TABLE ".$table[0].
" CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
1375 print
'<!-- '.$sql1.
' -->';
1376 print
'<!-- '.$sql2.
' -->';
1377 if ($force_utf8mb4_on_tables ==
'confirmed') {
1378 $resql1 = $db->query($sql1);
1380 $resql2 = $db->query($sql2);
1384 print
' - Done ('.(($resql1 && $resql2) ?
'OK' :
'KO').
')';
1386 print
' - Disabled';
1394 if ($force_utf8mb4_on_tables ==
'confirmed') {
1395 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1396 print
'<!-- '.$sql.
' -->';
1397 $resql = $db->query($sql);
1400 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1404if ($ok &&
GETPOST(
'force_collation_from_conf_on_tables',
'alpha')) {
1405 print
'<tr><td colspan="2"><br>*** Force page code and collation of tables into '.$conf->db->character_set.
'/'.$conf->db->dolibarr_main_db_collation.
' and row_format=dynamic (for mysql/mariadb only)</td></tr>';
1407 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1408 $force_collation_from_conf_on_tables =
GETPOST(
'force_collation_from_conf_on_tables',
'alpha');
1410 $listoftables = $db->DDLListTablesFull($db->database_name);
1413 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1414 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1415 print
'<!-- '.$sql.
' -->';
1416 $resql = $db->query($sql);
1419 foreach ($listoftables as $table) {
1421 if ($conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1424 if ($table[1] ==
'VIEW') {
1425 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' (Skipped)</td></tr>';
1429 print
'<tr><td colspan="2">';
1431 $sql1 =
"ALTER TABLE ".$table[0].
" ROW_FORMAT=dynamic";
1432 $sql2 =
"ALTER TABLE ".$table[0].
" CONVERT TO CHARACTER SET ".$conf->db->character_set.
" COLLATE ".$conf->db->dolibarr_main_db_collation;
1433 print
'<!-- '.$sql1.
' -->';
1434 print
'<!-- '.$sql2.
' -->';
1435 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1436 $resql1 = $db->query($sql1);
1438 $resql2 = $db->query($sql2);
1442 print
' - Done ('.(($resql1 && $resql2) ?
'OK' :
'KO').
')';
1444 print
' - Disabled';
1450 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1451 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1452 print
'<!-- '.$sql.
' -->';
1453 $resql = $db->query($sql);
1456 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1461if ($ok &&
GETPOST(
'rebuild_sequences',
'alpha')) {
1462 print
'<tr><td colspan="2"><br>*** Force to rebuild sequences (for postgresql only)</td></tr>';
1464 if ($db->type ==
"pgsql") {
1465 $rebuild_sequence =
GETPOST(
'rebuild_sequences',
'alpha');
1467 if ($rebuild_sequence ==
'confirmed') {
1468 $sql =
"SELECT dol_util_rebuild_sequences();";
1469 print
'<!-- '.$sql.
' -->';
1470 $resql = $db->query($sql);
1473 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1478if ($ok &&
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines')) {
1502 $repair_link_dispatch_lines_supplier_order_lines =
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha');
1505 echo
'<tr><th>Repair llx_receptiondet_batch.fk_commandefourndet</th></tr>';
1506 echo
'<tr><td>Repair in progress. This may take a while.</td></tr>';
1508 $sql_dispatch =
'SELECT * FROM '.MAIN_DB_PREFIX.
'receptiondet_batch WHERE COALESCE(fk_elementdet, 0) = 0';
1510 $resql_dispatch = $db->query($sql_dispatch);
1511 $n_processed_rows = 0;
1513 if ($resql_dispatch) {
1514 if ($db->num_rows($resql_dispatch) == 0) {
1515 echo
'<tr><td>Nothing to do.</td></tr>';
1518 while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
1519 $sql_line =
'SELECT line.rowid, line.qty FROM '.MAIN_DB_PREFIX.
'commande_fournisseurdet AS line';
1520 $sql_line .=
' WHERE line.fk_commande = '.((int) $obj_dispatch->fk_commande);
1521 $sql_line .=
' AND line.fk_product = '.((int) $obj_dispatch->fk_product);
1522 $resql_line = $db->query($sql_line);
1528 $remaining_qty = $obj_dispatch->qty;
1529 $first_iteration =
true;
1531 echo
'<tr><td>Unable to find a matching supplier order line for dispatch #'.$obj_dispatch->rowid.
'</td></tr>';
1532 $errors[] = $sql_line;
1533 $n_processed_rows++;
1536 if ($db->num_rows($resql_line) == 0) {
1539 while ($obj_line = $db->fetch_object($resql_line)) {
1540 if (!$remaining_qty) {
1543 if (!$obj_line->rowid) {
1546 $qty_for_line = min($remaining_qty, $obj_line->qty);
1547 if ($first_iteration) {
1548 $sql_attach =
'UPDATE '.MAIN_DB_PREFIX.
'receptiondet_batch';
1549 $sql_attach .=
' SET fk_elementdet = '.((int) $obj_line->rowid).
', qty = '.((float) $qty_for_line);
1550 $sql_attach .=
' WHERE rowid = '.((int) $obj_dispatch->rowid);
1551 $first_iteration =
false;
1553 $sql_attach_values = array(
1554 (
string) ((
int) $obj_dispatch->fk_element),
1555 (
string) ((
int) $obj_dispatch->fk_product),
1556 (
string) ((
int) $obj_line->rowid),
1557 (
string) ((
float) $qty_for_line),
1558 (
string) ((
int) $obj_dispatch->fk_entrepot),
1559 (
string) ((
int) $obj_dispatch->fk_user),
1560 $obj_dispatch->datec ?
"'".$db->idate($db->jdate($obj_dispatch->datec)).
"'" :
'NULL',
1561 $obj_dispatch->comment ?
"'".$db->escape($obj_dispatch->comment).
"'" :
'NULL',
1562 $obj_dispatch->
status ? (string) ((int) $obj_dispatch->
status) :
'NULL',
1563 $obj_dispatch->tms ?
"'".$db->idate($db->jdate($obj_dispatch->tms)).
"'" :
'NULL',
1564 $obj_dispatch->batch ?
"'".$db->escape($obj_dispatch->batch).
"'" :
'NULL',
1565 $obj_dispatch->eatby ?
"'".$db->escape($obj_dispatch->eatby).
"'" :
'NULL',
1566 $obj_dispatch->sellby ?
"'".$db->escape($obj_dispatch->sellby).
"'" :
'NULL'
1568 $sql_attach_values = implode(
', ', $sql_attach_values);
1570 $sql_attach =
'INSERT INTO '.MAIN_DB_PREFIX.
'receptiondet_batch';
1571 $sql_attach .=
' (fk_element, fk_product, fk_elementdet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)';
1572 $sql_attach .=
" VALUES (".$sql_attach_values.
")";
1575 if ($repair_link_dispatch_lines_supplier_order_lines ==
'confirmed') {
1576 $resql_attach = $db->query($sql_attach);
1578 $resql_attach =
true;
1581 if ($resql_attach) {
1582 $remaining_qty -= $qty_for_line;
1584 $errors[] = $sql_attach;
1587 $first_iteration =
false;
1589 $n_processed_rows++;
1592 if (!($n_processed_rows & 0xff)) {
1593 echo
'<tr><td>Processed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1599 echo
'<tr><td>Unable to find any dispatch without an fk_commandefourndet.'.
"</td></tr>\n";
1600 echo $sql_dispatch.
"\n";
1602 echo
'<tr><td>Fixed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1603 echo
'<tr><td>DONE.'.
"</td></tr>\n";
1605 if (count($errors)) {
1607 echo
'<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
1613 echo
'<tr><td><h3>SQL queries with errors:</h3></tr></td>';
1614 echo
'<tr><td>'.implode(
'</td></tr><tr><td>', $errors).
'</td></tr>';
1618if ($ok &&
GETPOST(
'repair_supplier_order_duplicate_ref')) {
1619 require_once DOL_DOCUMENT_ROOT .
'/fourn/class/fournisseur.commande.class.php';
1620 include_once DOL_DOCUMENT_ROOT .
'/societe/class/societe.class.php';
1627 $sql =
"SELECT * FROM " . MAIN_DB_PREFIX .
"commande_fournisseur";
1628 $sql .=
" WHERE ref IN (SELECT cf.ref FROM " . MAIN_DB_PREFIX .
"commande_fournisseur cf GROUP BY cf.ref, cf.entity HAVING COUNT(cf.rowid) > 1)";
1631 $duplicateSupplierOrders = [];
1632 $resql = $db->query($sql);
1634 while ($rawSupplierOrder = $db->fetch_object($resql)) {
1636 $supplierOrder->setVarsFromFetchObj($rawSupplierOrder);
1638 $duplicateSupplierOrders[$rawSupplierOrder->ref] [] = $supplierOrder;
1645 foreach ($duplicateSupplierOrders as $ref => $supplierOrders) {
1647 foreach (array_slice($supplierOrders, 1) as $supplierOrder) {
1650 $soc->fetch($supplierOrder->fourn_id);
1652 $newRef = $supplierOrder->getNextNumRef($soc);
1654 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"commande_fournisseur cf SET cf.ref = '" . $db->escape($newRef) .
"' WHERE cf.rowid = " . (int) $supplierOrder->id;
1655 if (!$db->query($sql)) {
1671if ($ok &&
GETPOST(
'recalculateinvoicetotal') ==
'confirmed') {
1674 $sql =
"SELECT f.rowid, SUM(fd.total_ht) as total_ht";
1675 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture f";
1676 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facturedet fd ON fd.fk_facture = f.rowid";
1677 $sql .=
" WHERE f.total_ht = 0";
1678 $sql .=
" GROUP BY fd.fk_facture HAVING SUM(fd.total_ht) <> 0";
1680 $resql = $db->query($sql);
1682 $num = $db->num_rows($resql);
1683 print
"We found ".$num.
" factures qualified that will have their total recalculated because they are at zero and line items not at zero\n";
1684 dol_syslog(
"We found ".$num.
" factures qualified that will have their total recalculated because they are at zero and line items not at zero");
1689 $obj = $db->fetch_object($resql);
1692 SUM(fd.total_ht) as 'total_ht',
1693 SUM(fd.total_tva) as 'total_tva',
1694 SUM(fd.total_localtax1) as 'localtax1',
1695 SUM(fd.total_localtax2) as 'localtax2',
1696 SUM(fd.total_ttc) as 'total_ttc'
1698 ".MAIN_DB_PREFIX.
"facturedet fd
1700 fd.fk_facture = $obj->rowid";
1701 $ressql_calculs = $db->query($sql_calculs);
1702 while ($obj_calcul = $db->fetch_object($ressql_calculs)) {
1704 UPDATE ".MAIN_DB_PREFIX.
"facture
1706 total_ht = ".($obj_calcul->total_ht ?
price2num($obj_calcul->total_ht,
'MT') : 0).
",
1707 total_tva = ".($obj_calcul->total_tva ?
price2num($obj_calcul->total_tva,
'MT') : 0).
",
1708 localtax1 = ".($obj_calcul->localtax1 ?
price2num($obj_calcul->localtax1,
'MT') : 0).
",
1709 localtax2 = ".($obj_calcul->localtax2 ?
price2num($obj_calcul->localtax2,
'MT') : 0).
",
1710 total_ttc = ".($obj_calcul->total_ttc ?
price2num($obj_calcul->total_ttc,
'MT') : 0).
"
1712 rowid = $obj->rowid";
1713 $db->query($sql_maj);
1718 print
"Pas de factures à traiter\n";
1722 dol_syslog(
"calculate_total_and_taxes.php: Error");
1735if (empty($actiondone)) {
1736 print
'<div class="error">'.$langs->trans(
"ErrorWrongParameters").
'</div>';
1740 print
'<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(GETPOSTISSET(
"login") ?
'&username='.urlencode(
GETPOST(
"login")) :
'').
'">';
1741 print $langs->trans(
"GoToDolibarr");
1748if ($db->connected) {
1753if (!$ok && isset($argv[1])) {
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
run_sql($sqlfile, $silent=1, $entity=0, $usesavepoint=1, $handler='', $okerror='default', $linelengthlimit=32768, $nocommentremoval=0, $offsetforchartofaccount=0, $colspan=0, $onlysqltoimportwebsite=0, $database='')
Launch a sql file.
Class for managing the social charges.
Class to manage predefined suppliers products.
Class to manage customers orders.
Class to manage contracts.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
dol_copy($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=0)
Copy a file to another file.
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.
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
dol_is_file($pathoffile)
Return if path is a file.
dol_dir_list($utf8_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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
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).
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
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).
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
pHeader($subtitle, $next, $action='set', $param='', $forcejqueryurl='', $csstable='main-inside')
Show HTML header of install pages.
pFooter($nonext=0, $setuplang='', $jscheckfunction='', $withpleasewait=0, $morehtml='')
Print HTML footer of install pages.
dolibarr_install_syslog($message, $level=LOG_DEBUG)
Log function for install pages.
clean_data_ecm_directories()
Clean data into ecm_directories table.
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.