30include_once
'inc.php';
31if (file_exists($conffile)) {
32 include_once $conffile;
46require_once $dolibarr_main_document_root.
'/core/lib/admin.lib.php';
47include_once $dolibarr_main_document_root.
'/core/lib/images.lib.php';
48require_once $dolibarr_main_document_root.
'/core/class/extrafields.class.php';
49require_once
'lib/repair.lib.php';
57$err = error_reporting();
62$setuplang =
GETPOST(
"selectlang",
'aZ09', 3) ?
GETPOST(
"selectlang",
'aZ09', 3) :
'auto';
63$langs->setDefaultLang($setuplang);
65$langs->loadLangs(array(
"admin",
"install",
"other"));
67if ($dolibarr_main_db_type ==
"mysqli") {
70if ($dolibarr_main_db_type ==
"pgsql") {
73if ($dolibarr_main_db_type ==
"mssql") {
79if (!is_object(
$conf)) {
88pHeader($langs->trans(
"Repair"),
"upgrade2",
GETPOST(
'action',
'aZ09'));
93print
'<div class="warning" style="padding-top: 10px">';
94print $langs->trans(
"SetAtLeastOneOptionAsUrlParameter");
101print
'Option standard is '.(GETPOST(
'standard',
'alpha') ?
GETPOST(
'standard',
'alpha') :
'undefined').
'<br>'.
"\n";
103print
'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";
105print
'Option restore_thirdparties_logos is '.(GETPOST(
'restore_thirdparties_logos',
'alpha') ?
GETPOST(
'restore_thirdparties_logos',
'alpha') :
'undefined').
'<br>'.
"\n";
106print
'Option restore_user_pictures is '.(GETPOST(
'restore_user_pictures',
'alpha') ?
GETPOST(
'restore_user_pictures',
'alpha') :
'undefined').
'<br>'.
"\n";
107print
'Option rebuild_product_thumbs is '.(GETPOST(
'rebuild_product_thumbs',
'alpha') ?
GETPOST(
'rebuild_product_thumbs',
'alpha') :
'undefined').
'<br>'.
"\n";
109print
'Option clean_linked_elements is '.(GETPOST(
'clean_linked_elements',
'alpha') ?
GETPOST(
'clean_linked_elements',
'alpha') :
'undefined').
'<br>'.
"\n";
110print
'Option clean_menus is '.(GETPOST(
'clean_menus',
'alpha') ?
GETPOST(
'clean_menus',
'alpha') :
'undefined').
'<br>'.
"\n";
111print
'Option clean_orphelin_dir is '.(GETPOST(
'clean_orphelin_dir',
'alpha') ?
GETPOST(
'clean_orphelin_dir',
'alpha') :
'undefined').
'<br>'.
"\n";
112print
'Option clean_product_stock_batch is '.(GETPOST(
'clean_product_stock_batch',
'alpha') ?
GETPOST(
'clean_product_stock_batch',
'alpha') :
'undefined').
'<br>'.
"\n";
113print
'Option clean_perm_table is '.(GETPOST(
'clean_perm_table',
'alpha') ?
GETPOST(
'clean_perm_table',
'alpha') :
'undefined').
'<br>'.
"\n";
114print
'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";
116print
'Option set_empty_time_spent_amount is '.(GETPOST(
'set_empty_time_spent_amount',
'alpha') ?
GETPOST(
'set_empty_time_spent_amount',
'alpha') :
'undefined').
'<br>'.
"\n";
118print
'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";
119print
'<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');
121if ($dolibarr_main_db_character_set !=
'utf8mb4') {
122 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.">';
125print
"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";
128print
'Option rebuild_sequences, for postgresql only, is '.(GETPOST(
'rebuild_sequences',
'alpha') ?
GETPOST(
'rebuild_sequences',
'alpha') :
'undefined').
'<br>'.
"\n";
133print
'<table cellspacing="0" cellpadding="1" class="centpercent">';
137if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass) || !empty($dolibarr_main_db_encrypted_pass)) {
138 require_once $dolibarr_main_document_root.
'/core/lib/security.lib.php';
139 if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass)) {
140 $dolibarr_main_db_pass = preg_replace(
'/crypted:/i',
'', $dolibarr_main_db_pass);
141 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_pass);
142 $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass;
144 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_encrypted_pass);
149$conf->db->type = $dolibarr_main_db_type;
150$conf->db->host = $dolibarr_main_db_host;
151$conf->db->port = $dolibarr_main_db_port;
152$conf->db->name = $dolibarr_main_db_name;
153$conf->db->user = $dolibarr_main_db_user;
154$conf->db->pass = $dolibarr_main_db_pass;
157$conf->db->dolibarr_main_db_encryption = isset($dolibarr_main_db_encryption) ? $dolibarr_main_db_encryption : 0;
158$conf->db->dolibarr_main_db_cryptkey = isset($dolibarr_main_db_cryptkey) ? $dolibarr_main_db_cryptkey :
'';
163 print
'<tr><td class="nowrap">';
164 print $langs->trans(
"ServerConnection").
" : $dolibarr_main_db_host</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
165 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ServerConnection").
": ".$dolibarr_main_db_host.$langs->transnoentities(
"OK"));
168 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->transnoentities(
"Error").
"</td></tr>";
169 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
174 if ($db->database_selected) {
175 print
'<tr><td class="nowrap">';
176 print $langs->trans(
"DatabaseConnection").
" : ".$dolibarr_main_db_name.
"</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
180 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->trans(
"Error").
"</td></tr>";
181 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
188 $version = $db->getVersion();
189 $versionarray = $db->getVersionArray();
190 print
'<tr><td>'.$langs->trans(
"ServerVersion").
'</td>';
191 print
'<td class="right">'.$version.
'</td></tr>';
196$conf->setValues($db);
198if (defined(
'SYSLOG_FILE')) {
199 $conf->global->SYSLOG_FILE = constant(
'SYSLOG_FILE');
201$conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
206$oneoptionset = (
GETPOST(
'standard',
'alpha') ||
GETPOST(
'restore_thirdparties_logos',
'alpha') ||
GETPOST(
'clean_linked_elements',
'alpha') ||
GETPOST(
'clean_menus',
'alpha')
207 ||
GETPOST(
'clean_orphelin_dir',
'alpha') ||
GETPOST(
'clean_product_stock_batch',
'alpha') ||
GETPOST(
'set_empty_time_spent_amount',
'alpha') ||
GETPOST(
'rebuild_product_thumbs',
'alpha')
208 ||
GETPOST(
'clean_perm_table',
'alpha')
209 ||
GETPOST(
'force_disable_of_modules_not_found',
'alpha')
210 ||
GETPOST(
'force_utf8_on_tables',
'alpha') ||
GETPOST(
'force_utf8mb4_on_tables',
'alpha') ||
GETPOST(
'force_collation_from_conf_on_tables',
'alpha')
211 ||
GETPOST(
'rebuild_sequences',
'alpha') ||
GETPOST(
'recalculateinvoicetotal',
'alpha'));
213if ($ok && $oneoptionset) {
215 print
'<tr><td colspan="2">'.$langs->trans(
"PleaseBePatient").
'<br><br></td></tr>';
221if ($ok &&
GETPOST(
'standard',
'alpha')) {
222 $dir =
"mysql/migration/";
229 $filesindir = array();
230 $handle = opendir($dir);
231 if (is_resource($handle)) {
232 while (($file = readdir($handle)) !==
false) {
233 if (preg_match(
'/\.sql$/i', $file)) {
234 $filesindir[] = $file;
240 foreach ($filesindir as $file) {
241 if (preg_match(
'/repair/i', $file)) {
247 foreach ($filelist as $file) {
248 print
'<tr><td class="nowrap">*** ';
249 print $langs->trans(
"Script").
'</td><td class="right">'.$file.
'</td></tr>';
251 $name = substr($file, 0,
dol_strlen($file) - 4);
254 $ok =
run_sql($dir.$file, 0, 0, 1);
261if ($ok &&
GETPOST(
'standard',
'alpha')) {
265 $listofmodulesextra = array(
'societe' =>
'societe',
'adherent' =>
'adherent',
'product' =>
'product',
266 'socpeople' =>
'socpeople',
'propal' =>
'propal',
'commande' =>
'commande',
267 'facture' =>
'facture',
'facturedet' =>
'facturedet',
'facture_rec' =>
'facture_rec',
'facturedet_rec' =>
'facturedet_rec',
268 'supplier_proposal' =>
'supplier_proposal',
'commande_fournisseur' =>
'commande_fournisseur',
269 'facture_fourn' =>
'facture_fourn',
'facture_fourn_rec' =>
'facture_fourn_rec',
'facture_fourn_det' =>
'facture_fourn_det',
'facture_fourn_det_rec' =>
'facture_fourn_det_rec',
270 'fichinter' =>
'fichinter',
'fichinterdet' =>
'fichinterdet',
271 'inventory' =>
'inventory',
272 'actioncomm' =>
'actioncomm',
'bom_bom' =>
'bom_bom',
'mrp_mo' =>
'mrp_mo',
273 'adherent_type' =>
'adherent_type',
'user' =>
'user',
'partnership' =>
'partnership',
'projet' =>
'projet',
'projet_task' =>
'projet_task',
'ticket' =>
'ticket');
276 print
'<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
277 foreach ($listofmodulesextra as $tablename => $elementtype) {
279 $tableextra = MAIN_DB_PREFIX.$tablename.
'_extrafields';
282 $arrayoffieldsdesc = $extrafields->fetch_name_optionals_label($elementtype);
285 $arrayoffieldsfound = array();
286 $resql = $db->DDLDescTable($tableextra);
288 print
'<tr><td>Check availability of extra field for '.$tableextra;
290 while ($obj = $db->fetch_object($resql)) {
291 $fieldname = $fieldtype =
'';
292 if (preg_match(
'/mysql/', $db->type)) {
293 $fieldname = $obj->Field;
294 $fieldtype = $obj->Type;
296 $fieldname = isset($obj->Key) ? $obj->Key : $obj->attname;
297 $fieldtype = isset($obj->Type) ? $obj->Type :
'varchar';
300 if (empty($fieldname)) {
303 if (in_array($fieldname, array(
'rowid',
'tms',
'fk_object',
'import_key'))) {
306 $arrayoffieldsfound[$fieldname] = array(
'type' => $fieldtype);
308 print
' - Found '.count($arrayoffieldsfound).
' fields into table';
309 if (count($arrayoffieldsfound) > 0) {
310 print
' <span class="opacitymedium">('.implode(
', ', array_keys($arrayoffieldsfound)).
')</span>';
315 foreach ($arrayoffieldsdesc as $code => $label) {
316 if (!in_array($code, array_keys($arrayoffieldsfound))) {
317 print
'Found field '.$code.
' declared into '.MAIN_DB_PREFIX.
'extrafields table but not found into desc of table '.$tableextra.
" -> ";
318 $type = $extrafields->attributes[$elementtype][
'type'][$code];
319 $length = $extrafields->attributes[$elementtype][
'size'][$code];
325 if ($type ==
'boolean') {
328 } elseif ($type ==
'price') {
331 } elseif ($type ==
'phone') {
334 } elseif ($type ==
'mail') {
337 } elseif (($type ==
'select') || ($type ==
'sellist') || ($type ==
'radio') || ($type ==
'checkbox') || ($type ==
'chkbxlst')) {
340 } elseif ($type ==
'link') {
350 'value' => $lengthdb,
351 'attribute' => $attribute,
352 'default' => $default,
359 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
360 $result = $db->DDLAddField($tableextra, $code, $field_desc,
"");
363 print
"KO ".$db->lasterror.
"<br>\n";
368 print
' - Mode test, no column added.';
373 print
"</td><td> </td></tr>\n";
375 print
'<tr><td>Table '.$tableextra.
' is not found</td><td></td></tr>'.
"\n";
382if ($ok &&
GETPOST(
'standard',
'alpha')) {
388if ($ok &&
GETPOST(
'standard',
'alpha')) {
389 print
'<tr><td colspan="2"><br>*** Clean constant record of modules not enabled</td></tr>';
391 $sql =
"SELECT name, entity, value";
392 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
393 $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'";
394 $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'";
395 $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_%'";
396 $sql .=
" OR name LIKE 'MAIN_MODULE_%_MODULEFOREXTERNAL'";
397 $sql .=
" ORDER BY name, entity";
399 $resql = $db->query($sql);
401 $num = $db->num_rows($resql);
408 $obj = $db->fetch_object($resql);
411 if (preg_match(
'/MAIN_MODULE_([^_]+)_(.+)/i', $obj->name, $reg)) {
415 $sql2 =
"SELECT COUNT(*) as nb";
416 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
417 $sql2 .=
" WHERE name = 'MAIN_MODULE_".$name.
"'";
418 $sql2 .=
" AND entity = ".((int) $obj->entity);
419 $resql2 = $db->query($sql2);
421 $obj2 = $db->fetch_object($resql2);
422 if ($obj2 && $obj2->nb == 0) {
424 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = '".$db->escape($obj->name).
"' AND entity = ".((int) $obj->entity);
426 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
427 $db->query($sqldelete);
429 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>';
431 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>';
451if ($ok &&
GETPOST(
'standard',
'alpha')) {
452 print
'<tr><td colspan="2"><br>*** Clean definition of boxes of modules not enabled</td></tr>';
454 $sql =
"SELECT file, entity FROM ".MAIN_DB_PREFIX.
"boxes_def";
455 $sql .=
" WHERE file like '%@%'";
457 $resql = $db->query($sql);
459 $num = $db->num_rows($resql);
466 $obj = $db->fetch_object($resql);
469 if (preg_match(
'/^(.+)@(.+)$/i', $obj->file, $reg)) {
473 $sql2 =
"SELECT COUNT(*) as nb";
474 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
475 $sql2 .=
" WHERE name = 'MAIN_MODULE_".strtoupper($module).
"'";
476 $sql2 .=
" AND entity = ".((int) $obj->entity);
477 $sql2 .=
" AND value <> 0";
478 $resql2 = $db->query($sql2);
480 $obj2 = $db->fetch_object($resql2);
481 if ($obj2 && $obj2->nb == 0) {
483 $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).
")";
484 $sqldeleteb =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def WHERE file = '".$db->escape($obj->file).
"' AND entity = ".((int) $obj->entity);
486 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
487 $db->query($sqldeletea);
488 $db->query($sqldeleteb);
490 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>';
492 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>';
510if ($ok &&
GETPOST(
'restore_thirdparties_logos')) {
515 print
'<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
517 $sql =
"SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX.
"societe as s ORDER BY s.nom";
518 $resql = $db->query($sql);
520 $num = $db->num_rows($resql);
524 $obj = $db->fetch_object($resql);
532 $tmp = explode(
'.', (
string) $obj->logo);
534 if (isset($tmp[1])) {
539 $filetotest = $dolibarr_main_data_root.
'/societe/logos/'.$name.$ext;
540 $filetotestsmall = $dolibarr_main_data_root.
'/societe/logos/thumbs/'.$name.
'_small'.$ext;
542 print
'Check thirdparty '.$obj->rowid.
' name='.$obj->name.
' logo='.$obj->logo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
544 $filetarget = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/'.$name.$ext;
545 $filetargetsmall = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs/'.$name.
'_small'.$ext;
548 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
549 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos');
552 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
553 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
554 dol_copy($filetotest, $filetarget,
'', 0);
560 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
561 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs');
563 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
564 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
565 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
584if ($ok &&
GETPOST(
'restore_user_pictures',
'alpha')) {
589 print
'<tr><td colspan="2"><br>*** Restore user pictures<br>';
591 $sql =
"SELECT s.rowid, s.firstname, s.lastname, s.login, s.photo FROM ".MAIN_DB_PREFIX.
"user as s ORDER BY s.rowid";
592 $resql = $db->query($sql);
594 $num = $db->num_rows($resql);
598 $obj = $db->fetch_object($resql);
606 $tmp = explode(
'.', (
string) $obj->photo);
608 if (isset($tmp[1])) {
613 $filetotest = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/'.$name.$ext;
614 $filetotestsmall = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_small'.$ext;
615 $filetotestmini = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_mini'.$ext;
617 print
'Check user '.$obj->rowid.
' lastname='.$obj->lastname.
' firstname='.$obj->firstname.
' photo='.$obj->photo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
619 $filetarget = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/'.$name.$ext;
620 $filetargetsmall = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_small'.$ext;
621 $filetargetmini = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_mini'.$ext;
625 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
626 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid);
629 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
630 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
631 dol_copy($filetotest, $filetarget,
'', 0);
637 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
638 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
641 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
642 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
643 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
649 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
650 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
653 print
" -> Copy file ".$filetotestmini.
" -> ".$filetargetmini.
"<br>\n";
654 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
655 dol_copy($filetotestmini, $filetargetmini,
'', 0);
673if ($ok &&
GETPOST(
'rebuild_product_thumbs',
'alpha')) {
675 global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
677 print
'<tr><td colspan="2"><br>*** Rebuild product thumbs<br>';
679 $sql =
"SELECT s.rowid, s.ref FROM ".MAIN_DB_PREFIX.
"product as s ORDER BY s.ref";
680 $resql = $db->query($sql);
682 $num = $db->num_rows($resql);
686 $obj = $db->fetch_object($resql);
688 if (!empty($obj->ref)) {
689 $files =
dol_dir_list($dolibarr_main_data_root.
'/produit/'.$obj->ref,
'files', 0);
690 foreach ($files as $file) {
693 $imgThumbSmall =
'notbuild';
694 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
696 $imgThumbSmall =
vignette($file[
'fullname'], $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
698 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbSmall.
" maxwidthsmall=".$maxwidthsmall.
" maxheightsmall=".$maxheightsmall.
"<br>\n";
699 $imgThumbMini =
'notbuild';
700 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
703 $imgThumbMini =
vignette($file[
'fullname'], $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
705 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbMini.
" maxwidthmini=".$maxwidthmini.
" maxheightmini=".$maxheightmini.
"<br>\n";
721if ($ok &&
GETPOST(
'clean_linked_elements',
'alpha')) {
722 print
'<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
724 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'commande').
"</td></tr>\n";
727 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'facture').
"</td></tr>\n";
730 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'facture').
"</td></tr>\n";
733 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'shipping').
"</td></tr>\n";
736 print
'<tr><td colspan="2">'.checkLinkedElements(
'shipping',
'delivery').
"</td></tr>\n";
739 print
'<tr><td colspan="2">'.checkLinkedElements(
'order_supplier',
'invoice_supplier').
"</td></tr>\n";
744if ($ok &&
GETPOST(
'clean_menus',
'alpha')) {
745 print
'<tr><td colspan="2"><br>*** Clean menu entries coming from disabled modules</td></tr>';
747 $sql =
"SELECT rowid, module";
748 $sql .=
" FROM ".MAIN_DB_PREFIX.
"menu as c";
749 $sql .=
" WHERE module IS NOT NULL AND module <> ''";
750 $sql .=
" ORDER BY module";
752 $resql = $db->query($sql);
754 $num = $db->num_rows($resql);
758 $obj = $db->fetch_object($resql);
760 $modulecond = $obj->module;
761 $modulecondarray = explode(
'|', $obj->module);
770 foreach ($modulecondarray as $tmpname) {
771 if ($tmpname ==
'margins') {
776 if (!empty(
$conf->$tmpname)) {
777 $result =
$conf->$tmpname->enabled;
784 if (!$moduleok && $modulecond) {
785 print
' - Module condition '.$modulecond.
' seems ko, we delete menu entry.';
786 if (
GETPOST(
'clean_menus') ==
'confirmed') {
787 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"menu WHERE module = '".$db->escape($modulecond).
"'";
788 $resql2 = $db->query($sql2);
793 print
' - <span class="warning">Cleaned</span>';
796 print
' - <span class="warning">Canceled (test mode)</span>';
799 print
' - Module condition '.$modulecond.
' is ok, we do nothing.';
818 print
'<tr><td>No menu entries of disabled menus found</td></tr>';
828if ($ok &&
GETPOST(
'clean_orphelin_dir',
'alpha')) {
829 $listmodulepart = array(
'company',
'invoice',
'invoice_supplier',
'propal',
'order',
'order_supplier',
'contract',
'tax');
830 foreach ($listmodulepart as $modulepart) {
831 $filearray = array();
832 $upload_dir = isset(
$conf->$modulepart->dir_output) ?
$conf->$modulepart->dir_output :
'';
833 if ($modulepart ==
'company') {
834 $upload_dir =
$conf->societe->dir_output;
836 if ($modulepart ==
'invoice') {
837 $upload_dir =
$conf->facture->dir_output;
839 if ($modulepart ==
'invoice_supplier') {
840 $upload_dir =
$conf->fournisseur->facture->dir_output;
842 if ($modulepart ==
'order') {
843 $upload_dir =
$conf->commande->dir_output;
845 if ($modulepart ==
'order_supplier') {
846 $upload_dir =
$conf->fournisseur->commande->dir_output;
848 if ($modulepart ==
'contract') {
849 $upload_dir =
$conf->contrat->dir_output;
852 if (empty($upload_dir)) {
856 print
'<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.
'</td></tr>';
858 $filearray =
dol_dir_list($upload_dir,
"files", 1,
'', array(
'^SPECIMEN\.pdf$',
'^\.',
'(\.meta|_preview.*\.png)$',
'^temp$',
'^payments$',
'^CVS$',
'^thumbs$'),
'', SORT_DESC, 1, 1);
861 if ($modulepart ==
'company') {
862 include_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
863 $object_instance =
new Societe($db);
865 if ($modulepart ==
'invoice') {
866 include_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
867 $object_instance =
new Facture($db);
868 } elseif ($modulepart ==
'invoice_supplier') {
869 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.facture.class.php';
871 } elseif ($modulepart ==
'propal') {
872 include_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
873 $object_instance =
new Propal($db);
874 } elseif ($modulepart ==
'order') {
875 include_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
876 $object_instance =
new Commande($db);
877 } elseif ($modulepart ==
'order_supplier') {
878 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
880 } elseif ($modulepart ==
'contract') {
881 include_once DOL_DOCUMENT_ROOT.
'/contrat/class/contrat.class.php';
882 $object_instance =
new Contrat($db);
883 } elseif ($modulepart ==
'tax') {
884 include_once DOL_DOCUMENT_ROOT.
'/compta/sociales/class/chargesociales.class.php';
888 foreach ($filearray as $key => $file) {
889 if (!is_dir($file[
'name'])
890 && $file[
'name'] !=
'.'
891 && $file[
'name'] !=
'..'
892 && $file[
'name'] !=
'CVS'
895 $relativefile = preg_replace(
'/'.preg_quote($upload_dir.
'/',
'/').
'/',
'', $file[
'fullname']);
900 $object_instance->id = 0;
901 $object_instance->ref =
'';
905 if ($modulepart ==
'invoice') {
906 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
909 if ($modulepart ==
'invoice_supplier') {
910 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg);
911 $id = empty($reg[1]) ?
'' : $reg[1];
913 if ($modulepart ==
'propal') {
914 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
917 if ($modulepart ==
'order') {
918 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
921 if ($modulepart ==
'order_supplier') {
922 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
925 if ($modulepart ==
'contract') {
926 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
929 if ($modulepart ==
'tax') {
930 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg);
934 if ((
$id || $ref) && $object_instance !==
null) {
936 $result = $object_instance->fetch(
$id, $ref);
940 print
'<tr><td colspan="2">';
941 print
'Delete orphelins file '.$file[
'fullname'].
'<br>';
942 if (
GETPOST(
'clean_orphelin_dir',
'alpha') ==
'confirmed') {
947 } elseif ($result < 0) {
948 print
'Error in '.get_class($object_instance).
'.fetch of id'.
$id.
' ref='.$ref.
', result='.$result.
'<br>';
957if ($ok &&
GETPOST(
'clean_product_stock_batch',
'alpha')) {
958 $methodtofix =
GETPOST(
'methodtofix',
'alpha') ?
GETPOST(
'methodtofix',
'alpha') :
'updatestock';
960 print
'<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
962 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
963 $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";
964 $sql .=
" WHERE p.rowid = ps.fk_product";
965 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
966 $sql .=
" HAVING (SUM(pb.qty) IS NOT NULL AND reel != SUM(pb.qty)) OR (SUM(pb.qty) IS NULL AND p.tobatch > 0)";
968 $resql = $db->query($sql);
970 $num = $db->num_rows($resql);
975 $obj = $db->fetch_object($resql);
976 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)';
979 if ($obj->reel != $obj->reelbatch) {
980 if (empty($obj->tobatch)) {
982 print
' -> Delete qty '.$obj->reelbatch.
' for any lot linked to fk_product_stock='.$obj->psrowid;
983 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_batch";
984 $sql2 .=
" WHERE fk_product_stock = ".((int) $obj->psrowid);
987 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
988 $resql2 = $db->query($sql2);
995 if ($methodtofix ==
'updatebatch') {
997 print
' -> Insert qty '.($obj->reel - $obj->reelbatch).
' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
998 $sql2 =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_batch(fk_product_stock, batch, qty)";
999 $sql2 .=
"VALUES(".((int) $obj->psrowid).
", '000000', ".((float) ($obj->reel - $obj->reelbatch)).
")";
1002 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
1003 $resql2 = $db->query($sql2);
1012 if ($methodtofix ==
'updatestock') {
1014 print
' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((float) $obj->reelbatch) :
'0').
' for ps.rowid = '.((
int) $obj->psrowid);
1015 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"product_stock";
1016 $sql2 .=
" SET reel = ".($obj->reelbatch ? ((float) $obj->reelbatch) :
'0').
" WHERE rowid = ".((
int) $obj->psrowid);
1019 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
1024 $resql2 = $db->query($sql2);
1027 $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)';
1028 $resql3 = $db->query($sql3);
1053 print
'<tr><td colspan="2">Nothing to do</td></tr>';
1062if ($ok &&
GETPOST(
'clean_product_stock_negative_if_batch',
'alpha')) {
1063 print
'<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
1065 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
1066 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product as p, ".MAIN_DB_PREFIX.
"product_stock as ps, ".MAIN_DB_PREFIX.
"product_batch as pb";
1067 $sql .=
" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
1068 $sql .=
" AND p.tobatch > 0";
1069 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
1070 $sql .=
" HAVING reel != SUM(pb.qty)";
1071 $resql = $db->query($sql);
1073 $num = $db->num_rows($resql);
1078 $obj = $db->fetch_object($resql);
1079 print
'<tr><td>'.$obj->rowid.
'-'.$obj->ref.
'-'.$obj->fk_entrepot.
' -> '.$obj->psrowid.
': '.$obj->reel.
' != '.$obj->reelbatch;
1088if ($ok &&
GETPOST(
'set_empty_time_spent_amount',
'alpha')) {
1089 print
'<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
1091 $sql =
"SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
1092 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"user as u";
1093 $sql .=
" WHERE ptt.fk_user = u.rowid";
1094 $sql .=
" AND ptt.thm IS NULL and u.thm > 0";
1095 $sql .=
" GROUP BY u.rowid, u.login, u.thm";
1097 $resql = $db->query($sql);
1099 $num = $db->num_rows($resql);
1104 $obj = $db->fetch_object($resql);
1105 print
'<tr><td>'.$obj->login.
'-'.$obj->user_id.
' ('.$obj->nb.
' lines to fix) -> '.$obj->user_thm;
1109 if (
GETPOST(
'set_empty_time_spent_amount') ==
'confirmed') {
1110 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"element_time";
1111 $sql2 .=
" SET thm = ".$obj->user_thm.
" WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id);
1112 $resql2 = $db->query($sql2);
1134 print
'<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
1143if ($ok &&
GETPOST(
'force_disable_of_modules_not_found',
'alpha')) {
1144 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>';
1146 $arraylistofkey = array(
'hooks',
'js',
'css');
1148 foreach ($arraylistofkey as $key) {
1149 $sql =
"SELECT DISTINCT name, value";
1150 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
1151 $sql .=
" WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($key).
"'";
1152 $sql .=
" ORDER BY name";
1154 $resql = $db->query($sql);
1156 $num = $db->num_rows($resql);
1160 $obj = $db->fetch_object($resql);
1161 $constantname = $obj->name;
1169 if (preg_match(
'/MAIN_MODULE_(.*)_'.strtoupper($key).
'/i', $constantname, $reg)) {
1170 $name = strtolower($reg[1]);
1176 if ($key ==
'hooks') {
1177 $reloffile = $name.
'/class/actions_'.$name.
'.class.php';
1180 $value = $obj->value;
1181 $valuearray = (array) json_decode($value);
1182 $reloffile = $valuearray[0];
1183 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1185 if ($key ==
'css') {
1186 $value = $obj->value;
1187 $valuearray = (array) json_decode($value);
1188 if ($value && (!is_array($valuearray) || count($valuearray) == 0)) {
1189 $valuearray = array();
1190 $valuearray[0] = $value;
1192 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1207 print
' - File of '.$key.
' ('.$reloffile.
') NOT found, we disable the module.';
1208 if (
GETPOST(
'force_disable_of_modules_not_found') ==
'confirmed') {
1209 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"_".strtoupper($key).
"'";
1210 $resql2 = $db->query($sql2);
1215 $sql3 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"'";
1216 $resql3 = $db->query($sql3);
1221 print
' - <span class="warning">Cleaned</span>';
1224 print
' - <span class="warning">Canceled (test mode)</span>';
1227 print
' - File of '.$key.
' ('.$reloffile.
') found, we do nothing.';
1247 print
'<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).
'</td></tr>';
1257if ($ok &&
GETPOST(
'clean_perm_table',
'alpha')) {
1258 print
'<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1261 foreach (
$conf->modules as $key => $val) {
1262 $listofmods .= ($listofmods ?
',' :
'').
"'".$db->escape($val).
"'";
1265 $sql =
"SELECT id, libelle as label, module from ".MAIN_DB_PREFIX.
"rights_def WHERE module NOT IN (".$db->sanitize($listofmods, 1).
") AND id > 100000";
1267 $resql = $db->query($sql);
1269 $num = $db->num_rows($resql);
1273 $obj = $db->fetch_object($resql);
1275 print
'<tr><td>Found line with id '.$obj->id.
', label "'.$obj->label.
'" of module "'.$obj->module.
'" to delete';
1276 if (
GETPOST(
'clean_perm_table',
'alpha') ==
'confirmed') {
1277 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def WHERE id = ".((int) $obj->id);
1278 $resqldelete = $db->query($sqldelete);
1279 if (!$resqldelete) {
1289 print
'<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1299if ($ok &&
GETPOST(
'force_utf8_on_tables',
'alpha')) {
1300 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>';
1302 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1303 $force_utf8_on_tables =
GETPOST(
'force_utf8_on_tables',
'alpha');
1305 $listoftables = $db->DDLListTablesFull($db->database_name);
1308 if ($force_utf8_on_tables ==
'confirmed') {
1309 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1310 print
'<!-- '.$sql.
' -->';
1311 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1312 $resql = $db->query($sql);
1315 $foreignkeystorestore = array();
1318 foreach ($listoftables as $table) {
1320 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1323 if ($table[1] ==
'VIEW') {
1324 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1329 $arrayofforeignkey = array(
1330 'llx_accounting_account' =>
'fk_accounting_account_fk_pcg_version',
1331 'llx_accounting_system' =>
'fk_accounting_account_fk_pcg_version',
1332 'llx_c_type_contact' =>
'fk_societe_commerciaux_fk_c_type_contact_code',
1333 'llx_societe_commerciaux' =>
'fk_societe_commerciaux_fk_c_type_contact_code'
1336 foreach ($arrayofforeignkey as $tmptable => $foreignkeyname) {
1337 if ($table[0] == $tmptable) {
1338 print
'<tr><td colspan="2">';
1339 $sqltmp =
"ALTER TABLE ".$db->sanitize($table[0]).
" DROP FOREIGN KEY ".$db->sanitize($foreignkeyname);
1341 if ($force_utf8_on_tables ==
'confirmed') {
1342 $resqltmp = $db->query($sqltmp);
1344 print
' - <span class="opacitymedium">Disabled</span>';
1347 $foreignkeystorestore[$tmptable] = $foreignkeyname;
1352 foreach ($listoftables as $table) {
1354 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1357 if ($table[1] ==
'VIEW') {
1358 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1362 $collation =
'utf8_unicode_ci';
1363 $defaultcollation = $db->getDefaultCollationDatabase();
1364 if (preg_match(
'/general/', $defaultcollation)) {
1365 $collation =
'utf8_general_ci';
1368 print
'<tr><td colspan="2">';
1370 $sql1 =
"ALTER TABLE ".$db->sanitize($table[0]).
" ROW_FORMAT=dynamic";
1371 $sql2 =
"ALTER TABLE ".$db->sanitize($table[0]).
" CONVERT TO CHARACTER SET utf8 COLLATE ".$db->sanitize($collation);
1372 print
'<!-- '.$sql1.
' -->';
1373 print
'<!-- '.$sql2.
' -->';
1374 if ($force_utf8_on_tables ==
'confirmed') {
1375 $resql1 = $db->query($sql1);
1377 $resql2 = $db->query($sql2);
1381 print
' - Done '.(($resql1 && $resql2) ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.
dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1383 print
' - <span class="opacitymedium">Disabled</span>';
1391 foreach ($foreignkeystorestore as $tmptable => $foreignkeyname) {
1392 $stringtofindinline =
"ALTER TABLE .* ADD CONSTRAINT ".$db->sanitize($foreignkeyname);
1393 $fileforkeys = DOL_DOCUMENT_ROOT.
'/install/mysql/tables/'.$tmptable.
'.key.sql';
1396 $handle = fopen($fileforkeys,
'r');
1398 while (($line = fgets($handle)) !==
false) {
1400 if (preg_match(
'/^'.$stringtofindinline.
'/i', $line)) {
1401 $resqltmp = $db->query($line);
1402 print
'<tr><td colspan="2">';
1404 print
' - Done '.($resqltmp ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1416 if ($force_utf8_on_tables ==
'confirmed') {
1417 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1418 print
'<!-- '.$sql.
' -->';
1419 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1420 $resql = $db->query($sql);
1423 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1428if ($ok &&
GETPOST(
'force_utf8mb4_on_tables',
'alpha')) {
1429 print
'<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8mb4/utf8mb4_unicode_ci (for mysql/mariadb only)</td></tr>';
1431 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1432 $force_utf8mb4_on_tables =
GETPOST(
'force_utf8mb4_on_tables',
'alpha');
1435 $listoftables = $db->DDLListTablesFull($db->database_name);
1438 if ($force_utf8mb4_on_tables ==
'confirmed') {
1439 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1440 print
'<!-- '.$sql.
' -->';
1441 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1442 $resql = $db->query($sql);
1445 $foreignkeystorestore = array();
1448 foreach ($listoftables as $table) {
1450 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1453 if ($table[1] ==
'VIEW') {
1454 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1459 $arrayofforeignkey = array(
1460 'llx_accounting_account' =>
'fk_accounting_account_fk_pcg_version',
1461 'llx_accounting_system' =>
'fk_accounting_account_fk_pcg_version',
1462 'llx_c_type_contact' =>
'fk_societe_commerciaux_fk_c_type_contact_code',
1463 'llx_societe_commerciaux' =>
'fk_societe_commerciaux_fk_c_type_contact_code'
1466 foreach ($arrayofforeignkey as $tmptable => $foreignkeyname) {
1467 if ($table[0] == $tmptable) {
1468 print
'<tr><td colspan="2">';
1469 $sqltmp =
"ALTER TABLE ".$db->sanitize($table[0]).
" DROP FOREIGN KEY ".$db->sanitize($foreignkeyname);
1471 if ($force_utf8mb4_on_tables ==
'confirmed') {
1472 $resqltmp = $db->query($sqltmp);
1474 print
' - <span class="opacitymedium">Disabled</span>';
1477 $foreignkeystorestore[$tmptable] = $foreignkeyname;
1482 foreach ($listoftables as $table) {
1484 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1487 if ($table[1] ==
'VIEW') {
1488 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1492 $collation =
'utf8mb4_unicode_ci';
1493 $defaultcollation = $db->getDefaultCollationDatabase();
1494 if (preg_match(
'/general/', $defaultcollation)) {
1495 $collation =
'utf8mb4_general_ci';
1498 print
'<tr><td colspan="2">';
1500 $sql1 =
"ALTER TABLE ".$db->sanitize($table[0]).
" ROW_FORMAT=dynamic";
1501 $sql2 =
"ALTER TABLE ".$db->sanitize($table[0]).
" CONVERT TO CHARACTER SET utf8mb4 COLLATE ".$db->sanitize($collation);
1502 print
'<!-- '.$sql1.
' -->';
1503 print
'<!-- '.$sql2.
' -->';
1504 if ($force_utf8mb4_on_tables ==
'confirmed') {
1505 $resql1 = $db->query($sql1);
1507 $resql2 = $db->query($sql2);
1511 print
' - Done '.(($resql1 && $resql2) ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.
dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1513 print
' - <span class="opacitymedium">Disabled</span>';
1521 foreach ($foreignkeystorestore as $tmptable => $foreignkeyname) {
1522 $stringtofindinline =
"ALTER TABLE .* ADD CONSTRAINT ".$db->sanitize($foreignkeyname);
1523 $fileforkeys = DOL_DOCUMENT_ROOT.
'/install/mysql/tables/'.$tmptable.
'.key.sql';
1526 $handle = fopen($fileforkeys,
'r');
1528 while (($line = fgets($handle)) !==
false) {
1530 if (preg_match(
'/^'.$stringtofindinline.
'/i', $line)) {
1531 $resqltmp = $db->query($line);
1532 print
'<tr><td colspan="2">';
1534 print
' - Done '.($resqltmp ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1546 if ($force_utf8mb4_on_tables ==
'confirmed') {
1547 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1548 print
'<!-- '.$sql.
' -->';
1549 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1550 $resql = $db->query($sql);
1553 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1557if ($ok &&
GETPOST(
'force_collation_from_conf_on_tables',
'alpha')) {
1558 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>';
1560 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1561 $force_collation_from_conf_on_tables =
GETPOST(
'force_collation_from_conf_on_tables',
'alpha');
1563 $listoftables = $db->DDLListTablesFull($db->database_name);
1566 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1567 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1568 print
'<!-- '.$sql.
' -->';
1569 $resql = $db->query($sql);
1572 foreach ($listoftables as $table) {
1574 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1577 if ($table[1] ==
'VIEW') {
1578 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' (Skipped)</td></tr>';
1582 print
'<tr><td colspan="2">';
1584 $sql1 =
"ALTER TABLE ".$table[0].
" ROW_FORMAT=dynamic";
1585 $sql2 =
"ALTER TABLE ".$table[0].
" CONVERT TO CHARACTER SET ".
$conf->db->character_set.
" COLLATE ".
$conf->db->dolibarr_main_db_collation;
1586 print
'<!-- '.$sql1.
' -->';
1587 print
'<!-- '.$sql2.
' -->';
1588 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1589 $resql1 = $db->query($sql1);
1591 $resql2 = $db->query($sql2);
1595 print
' - Done '.(($resql1 && $resql2) ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.
dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1597 print
' - <span class="opacitymedium">Disabled</span>';
1603 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1604 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1605 print
'<!-- '.$sql.
' -->';
1606 $resql = $db->query($sql);
1609 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1614if ($ok &&
GETPOST(
'rebuild_sequences',
'alpha')) {
1615 print
'<tr><td colspan="2"><br>*** Force to rebuild sequences (for postgresql only)</td></tr>';
1617 if ($db->type ==
"pgsql") {
1618 $rebuild_sequence =
GETPOST(
'rebuild_sequences',
'alpha');
1620 if ($rebuild_sequence ==
'confirmed') {
1621 $sql =
"SELECT dol_util_rebuild_sequences();";
1622 print
'<!-- '.$sql.
' -->';
1623 $resql = $db->query($sql);
1626 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1631if ($ok &&
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines')) {
1655 $repair_link_dispatch_lines_supplier_order_lines =
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha');
1658 echo
'<tr><th>Repair llx_receptiondet_batch.fk_commandefourndet</th></tr>';
1659 echo
'<tr><td>Repair in progress. This may take a while.</td></tr>';
1661 $sql_dispatch =
'SELECT * FROM '.MAIN_DB_PREFIX.
'receptiondet_batch WHERE COALESCE(fk_elementdet, 0) = 0';
1663 $resql_dispatch = $db->query($sql_dispatch);
1664 $n_processed_rows = 0;
1666 if ($resql_dispatch) {
1667 if ($db->num_rows($resql_dispatch) == 0) {
1668 echo
'<tr><td>Nothing to do.</td></tr>';
1671 while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
1672 $sql_line =
'SELECT line.rowid, line.qty FROM '.MAIN_DB_PREFIX.
'commande_fournisseurdet AS line';
1673 $sql_line .=
' WHERE line.fk_commande = '.((int) $obj_dispatch->fk_commande);
1674 $sql_line .=
' AND line.fk_product = '.((int) $obj_dispatch->fk_product);
1675 $resql_line = $db->query($sql_line);
1681 $remaining_qty = $obj_dispatch->qty;
1682 $first_iteration =
true;
1684 echo
'<tr><td>Unable to find a matching supplier order line for dispatch #'.$obj_dispatch->rowid.
'</td></tr>';
1685 $errors[] = $sql_line;
1686 $n_processed_rows++;
1689 if ($db->num_rows($resql_line) == 0) {
1692 while ($obj_line = $db->fetch_object($resql_line)) {
1693 if (!$remaining_qty) {
1696 if (!$obj_line->rowid) {
1699 $qty_for_line = min($remaining_qty, $obj_line->qty);
1700 if ($first_iteration) {
1701 $sql_attach =
'UPDATE '.MAIN_DB_PREFIX.
'receptiondet_batch';
1702 $sql_attach .=
' SET fk_elementdet = '.((int) $obj_line->rowid).
', qty = '.((float) $qty_for_line);
1703 $sql_attach .=
' WHERE rowid = '.((int) $obj_dispatch->rowid);
1704 $first_iteration =
false;
1706 $sql_attach_values = array(
1707 (
string) ((
int) $obj_dispatch->fk_element),
1708 (
string) ((
int) $obj_dispatch->fk_product),
1709 (
string) ((
int) $obj_line->rowid),
1710 (
string) ((
float) $qty_for_line),
1711 (
string) ((
int) $obj_dispatch->fk_entrepot),
1712 (
string) ((
int) $obj_dispatch->fk_user),
1713 $obj_dispatch->datec ?
"'".$db->idate($db->jdate($obj_dispatch->datec)).
"'" :
'NULL',
1714 $obj_dispatch->comment ?
"'".$db->escape($obj_dispatch->comment).
"'" :
'NULL',
1715 $obj_dispatch->
status ? (string) ((int) $obj_dispatch->
status) :
'NULL',
1716 $obj_dispatch->tms ?
"'".$db->idate($db->jdate($obj_dispatch->tms)).
"'" :
'NULL',
1717 $obj_dispatch->batch ?
"'".$db->escape($obj_dispatch->batch).
"'" :
'NULL',
1718 $obj_dispatch->eatby ?
"'".$db->escape($obj_dispatch->eatby).
"'" :
'NULL',
1719 $obj_dispatch->sellby ?
"'".$db->escape($obj_dispatch->sellby).
"'" :
'NULL'
1721 $sql_attach_values = implode(
', ', $sql_attach_values);
1723 $sql_attach =
'INSERT INTO '.MAIN_DB_PREFIX.
'receptiondet_batch';
1724 $sql_attach .=
' (fk_element, fk_product, fk_elementdet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)';
1725 $sql_attach .=
" VALUES (".$sql_attach_values.
")";
1728 if ($repair_link_dispatch_lines_supplier_order_lines ==
'confirmed') {
1729 $resql_attach = $db->query($sql_attach);
1731 $resql_attach =
true;
1734 if ($resql_attach) {
1735 $remaining_qty -= $qty_for_line;
1737 $errors[] = $sql_attach;
1740 $first_iteration =
false;
1742 $n_processed_rows++;
1745 if (!($n_processed_rows & 0xff)) {
1746 echo
'<tr><td>Processed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1752 echo
'<tr><td>Unable to find any dispatch without an fk_commandefourndet.'.
"</td></tr>\n";
1753 echo $sql_dispatch.
"\n";
1755 echo
'<tr><td>Fixed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1756 echo
'<tr><td>DONE.'.
"</td></tr>\n";
1758 if (count($errors)) {
1760 echo
'<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
1766 echo
'<tr><td><h3>SQL queries with errors:</h3></tr></td>';
1767 echo
'<tr><td>'.implode(
'</td></tr><tr><td>', $errors).
'</td></tr>';
1771if ($ok &&
GETPOST(
'repair_supplier_order_duplicate_ref')) {
1772 require_once DOL_DOCUMENT_ROOT .
'/fourn/class/fournisseur.commande.class.php';
1773 include_once DOL_DOCUMENT_ROOT .
'/societe/class/societe.class.php';
1780 $sql =
"SELECT * FROM " . MAIN_DB_PREFIX .
"commande_fournisseur";
1781 $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)";
1784 $duplicateSupplierOrders = [];
1785 $resql = $db->query($sql);
1787 while ($rawSupplierOrder = $db->fetch_object($resql)) {
1789 $supplierOrder->setVarsFromFetchObj($rawSupplierOrder);
1791 $duplicateSupplierOrders[$rawSupplierOrder->ref] [] = $supplierOrder;
1798 foreach ($duplicateSupplierOrders as $ref => $supplierOrders) {
1800 foreach (array_slice($supplierOrders, 1) as $supplierOrder) {
1803 $soc->fetch($supplierOrder->fourn_id);
1805 $newRef = $supplierOrder->getNextNumRef($soc);
1807 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"commande_fournisseur cf SET cf.ref = '" . $db->escape($newRef) .
"' WHERE cf.rowid = " . (int) $supplierOrder->id;
1808 if (!$db->query($sql)) {
1824if ($ok &&
GETPOST(
'recalculateinvoicetotal') ==
'confirmed') {
1827 $sql =
"SELECT f.rowid, SUM(fd.total_ht) as total_ht";
1828 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture f";
1829 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facturedet fd ON fd.fk_facture = f.rowid";
1830 $sql .=
" WHERE f.total_ht = 0";
1831 $sql .=
" GROUP BY fd.fk_facture HAVING SUM(fd.total_ht) <> 0";
1833 $resql = $db->query($sql);
1835 $num = $db->num_rows($resql);
1836 print
"We found ".$num.
" factures qualified that will have their total recalculated because they are at zero and line items not at zero\n";
1837 dol_syslog(
"We found ".$num.
" factures qualified that will have their total recalculated because they are at zero and line items not at zero");
1842 $obj = $db->fetch_object($resql);
1845 SUM(fd.total_ht) as 'total_ht',
1846 SUM(fd.total_tva) as 'total_tva',
1847 SUM(fd.total_localtax1) as 'localtax1',
1848 SUM(fd.total_localtax2) as 'localtax2',
1849 SUM(fd.total_ttc) as 'total_ttc'
1851 ".MAIN_DB_PREFIX.
"facturedet fd
1853 fd.fk_facture = $obj->rowid";
1854 $ressql_calculs = $db->query($sql_calculs);
1855 while ($obj_calcul = $db->fetch_object($ressql_calculs)) {
1857 UPDATE ".MAIN_DB_PREFIX.
"facture
1859 total_ht = ".($obj_calcul->total_ht ?
price2num($obj_calcul->total_ht,
'MT') : 0).
",
1860 total_tva = ".($obj_calcul->total_tva ?
price2num($obj_calcul->total_tva,
'MT') : 0).
",
1861 localtax1 = ".($obj_calcul->localtax1 ?
price2num($obj_calcul->localtax1,
'MT') : 0).
",
1862 localtax2 = ".($obj_calcul->localtax2 ?
price2num($obj_calcul->localtax2,
'MT') : 0).
",
1863 total_ttc = ".($obj_calcul->total_ttc ?
price2num($obj_calcul->total_ttc,
'MT') : 0).
"
1865 rowid = $obj->rowid";
1866 $db->query($sql_maj);
1871 print
"Pas de factures à traiter\n";
1875 dol_syslog(
"calculate_total_and_taxes.php: Error");
1888if (empty($actiondone)) {
1889 print
'<div class="error">'.$langs->trans(
"ErrorWrongParameters").
'</div>';
1893 print
'<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(GETPOSTISSET(
"login") ?
'&username='.urlencode(
GETPOST(
"login")) :
'').
'">';
1894 print $langs->trans(
"GoToDolibarr");
1901if ($db->connected) {
1906if (!$ok && isset($argv[1])) {
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 suppliers invoices.
Class to manage invoices.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
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.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
clean_data_ecm_directories()
Clean data into ecm_directories table.
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.