30include_once
'inc.php';
31if (file_exists($conffile)) {
32 include_once $conffile;
47@phan-var-force ?string $dolibarr_main_db_encryption
48@phan-var-force ?string $dolibarr_main_db_cryptkey
51require_once $dolibarr_main_document_root.
'/core/lib/admin.lib.php';
52include_once $dolibarr_main_document_root.
'/core/lib/images.lib.php';
53require_once $dolibarr_main_document_root.
'/core/class/extrafields.class.php';
54require_once
'lib/repair.lib.php';
62$err = error_reporting();
67$setuplang =
GETPOST(
"selectlang",
'aZ09', 3) ?
GETPOST(
"selectlang",
'aZ09', 3) :
'auto';
68$langs->setDefaultLang($setuplang);
70$langs->loadLangs(array(
"admin",
"install",
"other"));
72if ($dolibarr_main_db_type ==
"mysqli") {
75if ($dolibarr_main_db_type ==
"pgsql") {
78if ($dolibarr_main_db_type ==
"mssql") {
84if (!is_object(
$conf)) {
93pHeader($langs->trans(
"Repair"),
"upgrade2",
GETPOST(
'action',
'aZ09'));
98print
'<div class="warning" style="padding-top: 10px">';
99print $langs->trans(
"SetAtLeastOneOptionAsUrlParameter");
106print
'Option standard is '.(GETPOST(
'standard',
'alpha') ?
GETPOST(
'standard',
'alpha') :
'undefined').
'<br>'.
"\n";
108print
'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";
110print
'Option restore_thirdparties_logos is '.(GETPOST(
'restore_thirdparties_logos',
'alpha') ?
GETPOST(
'restore_thirdparties_logos',
'alpha') :
'undefined').
'<br>'.
"\n";
111print
'Option restore_user_pictures is '.(GETPOST(
'restore_user_pictures',
'alpha') ?
GETPOST(
'restore_user_pictures',
'alpha') :
'undefined').
'<br>'.
"\n";
112print
'Option rebuild_product_thumbs is '.(GETPOST(
'rebuild_product_thumbs',
'alpha') ?
GETPOST(
'rebuild_product_thumbs',
'alpha') :
'undefined').
'<br>'.
"\n";
114print
'Option clean_linked_elements is '.(GETPOST(
'clean_linked_elements',
'alpha') ?
GETPOST(
'clean_linked_elements',
'alpha') :
'undefined').
'<br>'.
"\n";
115print
'Option clean_menus is '.(GETPOST(
'clean_menus',
'alpha') ?
GETPOST(
'clean_menus',
'alpha') :
'undefined').
'<br>'.
"\n";
116print
'Option clean_orphelin_dir is '.(GETPOST(
'clean_orphelin_dir',
'alpha') ?
GETPOST(
'clean_orphelin_dir',
'alpha') :
'undefined').
'<br>'.
"\n";
117print
'Option clean_product_stock_batch is '.(GETPOST(
'clean_product_stock_batch',
'alpha') ?
GETPOST(
'clean_product_stock_batch',
'alpha') :
'undefined').
'<br>'.
"\n";
118print
'Option clean_perm_table is '.(GETPOST(
'clean_perm_table',
'alpha') ?
GETPOST(
'clean_perm_table',
'alpha') :
'undefined').
'<br>'.
"\n";
119print
'Option clean_ecm_files_table is '.(GETPOST(
'clean_ecm_files_table',
'alpha') ?
GETPOST(
'clean_ecm_files_table',
'alpha') :
'undefined').
'<br>'.
"\n";
120print
'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";
122print
'Option set_empty_time_spent_amount is '.(GETPOST(
'set_empty_time_spent_amount',
'alpha') ?
GETPOST(
'set_empty_time_spent_amount',
'alpha') :
'undefined').
'<br>'.
"\n";
124print
'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";
125print
'<span class="valignmiddle">'.
"Option force_utf8mb4_on_tables (force utf8mb4 + row=dynamic), for mysql/mariadb only, is ".(
GETPOST(
'force_utf8mb4_on_tables',
'alpha') ?
GETPOST(
'force_utf8mb4_on_tables',
'alpha') :
'undefined');
127if ($dolibarr_main_db_character_set !=
'utf8mb4') {
128 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.">';
131print
"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";
134print
'Option rebuild_sequences, for postgresql only, is '.(GETPOST(
'rebuild_sequences',
'alpha') ?
GETPOST(
'rebuild_sequences',
'alpha') :
'undefined').
'<br>'.
"\n";
139print
'<table cellspacing="0" cellpadding="1" class="centpercent">';
143if (preg_match(
'/(crypted|dolcrypt):/i', $dolibarr_main_db_pass) || !empty($dolibarr_main_db_encrypted_pass)) {
144 require_once $dolibarr_main_document_root.
'/core/lib/security.lib.php';
145 if (preg_match(
'/crypted:/i', $dolibarr_main_db_pass)) {
146 $dolibarr_main_db_pass = preg_replace(
'/crypted:/i',
'', $dolibarr_main_db_pass);
147 $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass;
148 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_pass);
149 } elseif (preg_match(
'/dolcrypt:/i', $dolibarr_main_db_pass)) {
150 $dolibarr_main_db_encrypted_pass = $dolibarr_main_db_pass;
151 $dolibarr_main_db_pass =
dolDecrypt($dolibarr_main_db_pass);
153 $dolibarr_main_db_pass =
dol_decode($dolibarr_main_db_encrypted_pass);
158$conf->db->type = $dolibarr_main_db_type;
159$conf->db->host = $dolibarr_main_db_host;
160$conf->db->port = $dolibarr_main_db_port;
161$conf->db->name = $dolibarr_main_db_name;
162$conf->db->user = $dolibarr_main_db_user;
163$conf->db->pass = $dolibarr_main_db_pass;
166$conf->db->dolibarr_main_db_encryption = isset($dolibarr_main_db_encryption) ? $dolibarr_main_db_encryption : 0;
167$conf->db->dolibarr_main_db_cryptkey = isset($dolibarr_main_db_cryptkey) ? $dolibarr_main_db_cryptkey :
'';
172 print
'<tr><td class="nowrap">';
173 print $langs->trans(
"ServerConnection").
" : $dolibarr_main_db_host</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
174 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ServerConnection").
": ".$dolibarr_main_db_host.$langs->transnoentities(
"OK"));
177 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->transnoentities(
"Error").
"</td></tr>";
178 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
183 if ($db->database_selected) {
184 print
'<tr><td class="nowrap">';
185 print $langs->trans(
"DatabaseConnection").
" : ".$dolibarr_main_db_name.
"</td><td class=\"right\">".$langs->trans(
"OK").
"</td></tr>";
189 print
"<tr><td>".$langs->trans(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name).
"</td><td class=\"right\">".$langs->trans(
"Error").
"</td></tr>";
190 dolibarr_install_syslog(
"repair: ".$langs->transnoentities(
"ErrorFailedToConnectToDatabase", $dolibarr_main_db_name));
197 $version = $db->getVersion();
198 $versionarray = $db->getVersionArray();
199 print
'<tr><td>'.$langs->trans(
"ServerVersion").
'</td>';
200 print
'<td class="right">'.$version.
'</td></tr>';
205$conf->setValues($db);
207if (defined(
'SYSLOG_FILE')) {
208 $conf->global->SYSLOG_FILE = constant(
'SYSLOG_FILE');
210$conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
215$oneoptionset = (
GETPOST(
'standard',
'alpha') ||
GETPOST(
'restore_thirdparties_logos',
'alpha') ||
GETPOST(
'clean_linked_elements',
'alpha') ||
GETPOST(
'clean_menus',
'alpha')
216 ||
GETPOST(
'clean_orphelin_dir',
'alpha') ||
GETPOST(
'clean_product_stock_batch',
'alpha') ||
GETPOST(
'set_empty_time_spent_amount',
'alpha') ||
GETPOST(
'rebuild_product_thumbs',
'alpha')
217 ||
GETPOST(
'clean_perm_table',
'alpha') ||
GETPOST(
'clean_ecm_files_table',
'alpha')
218 ||
GETPOST(
'force_disable_of_modules_not_found',
'alpha')
219 ||
GETPOST(
'force_utf8_on_tables',
'alpha') ||
GETPOST(
'force_utf8mb4_on_tables',
'alpha') ||
GETPOST(
'force_collation_from_conf_on_tables',
'alpha')
220 ||
GETPOST(
'rebuild_sequences',
'alpha') ||
GETPOST(
'recalculateinvoicetotal',
'alpha'));
222if ($ok && $oneoptionset) {
224 print
'<tr><td colspan="2">'.$langs->trans(
"PleaseBePatient").
'<br><br></td></tr>';
230if ($ok &&
GETPOST(
'standard',
'alpha')) {
231 $dir =
"mysql/migration/";
238 $filesindir = array();
239 $handle = opendir($dir);
240 if (is_resource($handle)) {
241 while (($file = readdir($handle)) !==
false) {
242 if (preg_match(
'/\.sql$/i', $file)) {
243 $filesindir[] = $file;
249 foreach ($filesindir as $file) {
250 if (preg_match(
'/repair/i', $file)) {
256 foreach ($filelist as $file) {
257 print
'<tr><td class="nowrap">*** ';
258 print $langs->trans(
"Script").
'</td><td class="right">'.$file.
'</td></tr>';
260 $name = substr($file, 0,
dol_strlen($file) - 4);
263 $ok =
run_sql($dir.$file, 0, 0, 1);
270if ($ok &&
GETPOST(
'standard',
'alpha')) {
274 $listofmodulesextra = array(
'societe' =>
'societe',
'adherent' =>
'adherent',
'product' =>
'product',
275 'socpeople' =>
'socpeople',
'propal' =>
'propal',
'commande' =>
'commande',
276 'facture' =>
'facture',
'facturedet' =>
'facturedet',
'facture_rec' =>
'facture_rec',
'facturedet_rec' =>
'facturedet_rec',
277 'supplier_proposal' =>
'supplier_proposal',
'commande_fournisseur' =>
'commande_fournisseur',
278 'facture_fourn' =>
'facture_fourn',
'facture_fourn_rec' =>
'facture_fourn_rec',
'facture_fourn_det' =>
'facture_fourn_det',
'facture_fourn_det_rec' =>
'facture_fourn_det_rec',
279 'fichinter' =>
'fichinter',
'fichinterdet' =>
'fichinterdet',
280 'inventory' =>
'inventory',
281 'actioncomm' =>
'actioncomm',
'bom_bom' =>
'bom_bom',
'mrp_mo' =>
'mrp_mo',
282 'adherent_type' =>
'adherent_type',
'user' =>
'user',
'partnership' =>
'partnership',
'projet' =>
'projet',
'projet_task' =>
'projet_task',
'ticket' =>
'ticket');
285 print
'<tr><td colspan="2"><br>*** Check fields into extra table structure match table of definition. If not add column into table</td></tr>';
286 foreach ($listofmodulesextra as $tablename => $elementtype) {
288 $tableextra = MAIN_DB_PREFIX.$tablename.
'_extrafields';
291 $arrayoffieldsdesc = $extrafields->fetch_name_optionals_label($elementtype);
294 $arrayoffieldsfound = array();
295 $resql = $db->DDLDescTable($tableextra);
297 print
'<tr><td>Check availability of extra field for '.$tableextra;
299 while ($obj = $db->fetch_object($resql)) {
300 $fieldname = $fieldtype =
'';
301 if (preg_match(
'/mysql/', $db->type)) {
302 $fieldname = $obj->Field;
303 $fieldtype = $obj->Type;
305 $fieldname = isset($obj->Key) ? $obj->Key : $obj->attname;
306 $fieldtype = isset($obj->Type) ? $obj->Type :
'varchar';
309 if (empty($fieldname)) {
312 if (in_array($fieldname, array(
'rowid',
'tms',
'fk_object',
'import_key'))) {
315 $arrayoffieldsfound[$fieldname] = array(
'type' => $fieldtype);
317 print
' - Found '.count($arrayoffieldsfound).
' fields into table';
318 if (count($arrayoffieldsfound) > 0) {
319 print
' <span class="opacitymedium">('.implode(
', ', array_keys($arrayoffieldsfound)).
')</span>';
324 foreach ($arrayoffieldsdesc as $code => $label) {
325 if (!in_array($code, array_keys($arrayoffieldsfound))) {
326 print
'Found field '.$code.
' declared into '.MAIN_DB_PREFIX.
'extrafields table but not found into desc of table '.$tableextra.
" -> ";
327 $type = $extrafields->attributes[$elementtype][
'type'][$code];
328 $length = $extrafields->attributes[$elementtype][
'size'][$code];
334 if ($type ==
'boolean') {
337 } elseif ($type ==
'price') {
340 } elseif ($type ==
'phone') {
343 } elseif ($type ==
'mail') {
346 } elseif (($type ==
'select') || ($type ==
'sellist') || ($type ==
'radio') || ($type ==
'checkbox') || ($type ==
'chkbxlst')) {
349 } elseif ($type ==
'link') {
359 'value' => $lengthdb,
360 'attribute' => $attribute,
361 'default' => $default,
368 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
369 $result = $db->DDLAddField($tableextra, $code, $field_desc,
"");
372 print
"KO ".$db->lasterror.
"<br>\n";
377 print
' - Mode test, no column added.';
382 print
"</td><td> </td></tr>\n";
384 print
'<tr><td>Table '.$tableextra.
' is not found</td><td></td></tr>'.
"\n";
391if ($ok &&
GETPOST(
'standard',
'alpha')) {
397if ($ok &&
GETPOST(
'standard',
'alpha')) {
398 print
'<tr><td colspan="2"><br>*** Clean constant record of modules not enabled</td></tr>';
400 $sql =
"SELECT name, entity, value";
401 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
402 $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'";
403 $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'";
404 $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_%'";
405 $sql .=
" OR name LIKE 'MAIN_MODULE_%_MODULEFOREXTERNAL'";
406 $sql .=
" ORDER BY name, entity";
408 $resql = $db->query($sql);
410 $num = $db->num_rows($resql);
417 $obj = $db->fetch_object($resql);
420 if (preg_match(
'/MAIN_MODULE_([^_]+)_(.+)/i', $obj->name, $reg)) {
424 $sql2 =
"SELECT COUNT(*) as nb";
425 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
426 $sql2 .=
" WHERE name = 'MAIN_MODULE_".$name.
"'";
427 $sql2 .=
" AND entity = ".((int) $obj->entity);
428 $resql2 = $db->query($sql2);
430 $obj2 = $db->fetch_object($resql2);
431 if ($obj2 && $obj2->nb == 0) {
433 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = '".$db->escape($obj->name).
"' AND entity = ".((int) $obj->entity);
435 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
436 $db->query($sqldelete);
438 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>';
440 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>';
460if ($ok &&
GETPOST(
'standard',
'alpha')) {
461 print
'<tr><td colspan="2"><br>*** Clean definition of boxes of modules not enabled</td></tr>';
463 $sql =
"SELECT file, entity FROM ".MAIN_DB_PREFIX.
"boxes_def";
464 $sql .=
" WHERE file like '%@%'";
466 $resql = $db->query($sql);
468 $num = $db->num_rows($resql);
475 $obj = $db->fetch_object($resql);
478 if (preg_match(
'/^(.+)@(.+)$/i', $obj->file, $reg)) {
482 $sql2 =
"SELECT COUNT(*) as nb";
483 $sql2 .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
484 $sql2 .=
" WHERE name = 'MAIN_MODULE_".strtoupper($module).
"'";
485 $sql2 .=
" AND entity = ".((int) $obj->entity);
486 $sql2 .=
" AND value <> 0";
487 $resql2 = $db->query($sql2);
489 $obj2 = $db->fetch_object($resql2);
490 if ($obj2 && $obj2->nb == 0) {
492 $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).
")";
493 $sqldeleteb =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def WHERE file = '".$db->escape($obj->file).
"' AND entity = ".((int) $obj->entity);
495 if (
GETPOST(
'standard',
'alpha') ==
'confirmed') {
496 $db->query($sqldeletea);
497 $db->query($sqldeleteb);
499 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>';
501 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>';
519if ($ok &&
GETPOST(
'restore_thirdparties_logos')) {
524 print
'<tr><td colspan="2"><br>*** Restore thirdparties logo<br>';
526 $sql =
"SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX.
"societe as s ORDER BY s.nom";
527 $resql = $db->query($sql);
529 $num = $db->num_rows($resql);
533 $obj = $db->fetch_object($resql);
541 $tmp = explode(
'.', (
string) $obj->logo);
543 if (isset($tmp[1])) {
548 $filetotest = $dolibarr_main_data_root.
'/societe/logos/'.$name.$ext;
549 $filetotestsmall = $dolibarr_main_data_root.
'/societe/logos/thumbs/'.$name.
'_small'.$ext;
551 print
'Check thirdparty '.$obj->rowid.
' name='.$obj->name.
' logo='.$obj->logo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
553 $filetarget = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/'.$name.$ext;
554 $filetargetsmall = $dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs/'.$name.
'_small'.$ext;
557 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
558 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos');
561 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
562 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
563 dol_copy($filetotest, $filetarget,
'', 0);
569 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
570 dol_mkdir($dolibarr_main_data_root.
'/societe/'.$obj->rowid.
'/logos/thumbs');
572 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
573 if (
GETPOST(
'restore_thirdparties_logos',
'alpha') ==
'confirmed') {
574 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
593if ($ok &&
GETPOST(
'restore_user_pictures',
'alpha')) {
598 print
'<tr><td colspan="2"><br>*** Restore user pictures<br>';
600 $sql =
"SELECT s.rowid, s.firstname, s.lastname, s.login, s.photo FROM ".MAIN_DB_PREFIX.
"user as s ORDER BY s.rowid";
601 $resql = $db->query($sql);
603 $num = $db->num_rows($resql);
607 $obj = $db->fetch_object($resql);
615 $tmp = explode(
'.', (
string) $obj->photo);
617 if (isset($tmp[1])) {
622 $filetotest = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/'.$name.$ext;
623 $filetotestsmall = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_small'.$ext;
624 $filetotestmini = $dolibarr_main_data_root.
'/users/'.substr(sprintf(
'%08d', $obj->rowid), -1, 1).
'/'.substr(sprintf(
'%08d', $obj->rowid), -2, 1).
'/thumbs/'.$name.
'_mini'.$ext;
626 print
'Check user '.$obj->rowid.
' lastname='.$obj->lastname.
' firstname='.$obj->firstname.
' photo='.$obj->photo.
' file '.$filetotest.
" exists=".$exists.
"<br>\n";
628 $filetarget = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/'.$name.$ext;
629 $filetargetsmall = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_small'.$ext;
630 $filetargetmini = $dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs/'.$name.
'_mini'.$ext;
634 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
635 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid);
638 print
" -> Copy file ".$filetotest.
" -> ".$filetarget.
"<br>\n";
639 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
640 dol_copy($filetotest, $filetarget,
'', 0);
646 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
647 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
650 print
" -> Copy file ".$filetotestsmall.
" -> ".$filetargetsmall.
"<br>\n";
651 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
652 dol_copy($filetotestsmall, $filetargetsmall,
'', 0);
658 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
659 dol_mkdir($dolibarr_main_data_root.
'/users/'.$obj->rowid.
'/thumbs');
662 print
" -> Copy file ".$filetotestmini.
" -> ".$filetargetmini.
"<br>\n";
663 if (
GETPOST(
'restore_user_pictures',
'alpha') ==
'confirmed') {
664 dol_copy($filetotestmini, $filetargetmini,
'', 0);
682if ($ok &&
GETPOST(
'rebuild_product_thumbs',
'alpha')) {
684 global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
686 print
'<tr><td colspan="2"><br>*** Rebuild product thumbs<br>';
688 $sql =
"SELECT s.rowid, s.ref FROM ".MAIN_DB_PREFIX.
"product as s ORDER BY s.ref";
689 $resql = $db->query($sql);
691 $num = $db->num_rows($resql);
695 $obj = $db->fetch_object($resql);
697 if (!empty($obj->ref)) {
698 $files =
dol_dir_list($dolibarr_main_data_root.
'/produit/'.$obj->ref,
'files', 0);
699 foreach ($files as $file) {
702 $imgThumbSmall =
'notbuild';
703 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
705 $imgThumbSmall =
vignette($file[
'fullname'], $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
707 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbSmall.
" maxwidthsmall=".$maxwidthsmall.
" maxheightsmall=".$maxheightsmall.
"<br>\n";
708 $imgThumbMini =
'notbuild';
709 if (
GETPOST(
'rebuild_product_thumbs',
'alpha') ==
'confirmed') {
712 $imgThumbMini =
vignette($file[
'fullname'], $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
714 print
'Check product '.$obj->rowid.
", file ".$file[
'fullname'].
" -> ".$imgThumbMini.
" maxwidthmini=".$maxwidthmini.
" maxheightmini=".$maxheightmini.
"<br>\n";
730if ($ok &&
GETPOST(
'clean_linked_elements',
'alpha')) {
731 print
'<tr><td colspan="2"><br>*** Check table of linked elements and delete orphelins links</td></tr>';
733 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'commande').
"</td></tr>\n";
736 print
'<tr><td colspan="2">'.checkLinkedElements(
'propal',
'facture').
"</td></tr>\n";
739 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'facture').
"</td></tr>\n";
742 print
'<tr><td colspan="2">'.checkLinkedElements(
'commande',
'shipping').
"</td></tr>\n";
745 print
'<tr><td colspan="2">'.checkLinkedElements(
'shipping',
'delivery').
"</td></tr>\n";
748 print
'<tr><td colspan="2">'.checkLinkedElements(
'order_supplier',
'invoice_supplier').
"</td></tr>\n";
753if ($ok &&
GETPOST(
'clean_menus',
'alpha')) {
754 print
'<tr><td colspan="2"><br>*** Clean menu entries coming from disabled modules</td></tr>';
756 $sql =
"SELECT rowid, module";
757 $sql .=
" FROM ".MAIN_DB_PREFIX.
"menu as c";
758 $sql .=
" WHERE module IS NOT NULL AND module <> ''";
759 $sql .=
" ORDER BY module";
761 $resql = $db->query($sql);
763 $num = $db->num_rows($resql);
767 $obj = $db->fetch_object($resql);
769 $modulecond = $obj->module;
770 $modulecondarray = explode(
'|', $obj->module);
779 foreach ($modulecondarray as $tmpname) {
780 if ($tmpname ==
'margins') {
785 if (!empty(
$conf->$tmpname)) {
786 $result =
$conf->$tmpname->enabled;
793 if (!$moduleok && $modulecond) {
794 print
' - Module condition '.$modulecond.
' seems ko, we delete menu entry.';
795 if (
GETPOST(
'clean_menus') ==
'confirmed') {
796 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"menu WHERE module = '".$db->escape($modulecond).
"'";
797 $resql2 = $db->query($sql2);
802 print
' - <span class="warning">Cleaned</span>';
805 print
' - <span class="warning">Canceled (test mode)</span>';
808 print
' - Module condition '.$modulecond.
' is ok, we do nothing.';
827 print
'<tr><td>No menu entries of disabled menus found</td></tr>';
837if ($ok &&
GETPOST(
'clean_orphelin_dir',
'alpha')) {
838 $listmodulepart = array(
'company',
'invoice',
'invoice_supplier',
'propal',
'order',
'order_supplier',
'contract',
'tax');
839 foreach ($listmodulepart as $modulepart) {
840 $filearray = array();
841 $upload_dir = isset(
$conf->$modulepart->dir_output) ?
$conf->$modulepart->dir_output :
'';
842 if ($modulepart ==
'company') {
843 $upload_dir =
$conf->societe->dir_output;
845 if ($modulepart ==
'invoice') {
846 $upload_dir =
$conf->facture->dir_output;
848 if ($modulepart ==
'invoice_supplier') {
849 $upload_dir =
$conf->fournisseur->facture->dir_output;
851 if ($modulepart ==
'order') {
852 $upload_dir =
$conf->commande->dir_output;
854 if ($modulepart ==
'order_supplier') {
855 $upload_dir =
$conf->fournisseur->commande->dir_output;
857 if ($modulepart ==
'contract') {
858 $upload_dir =
$conf->contrat->dir_output;
861 if (empty($upload_dir)) {
865 print
'<tr><td colspan="2"><br>*** Clean orphelins files into files '.$upload_dir.
'</td></tr>';
867 $filearray =
dol_dir_list($upload_dir,
"files", 1,
'', array(
'^SPECIMEN\.pdf$',
'^\.',
'(\.meta|_preview.*\.png)$',
'^temp$',
'^payments$',
'^CVS$',
'^thumbs$'),
'', SORT_DESC, 1, 1);
869 $object_instance =
null;
871 if ($modulepart ==
'company') {
872 include_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
873 $object_instance =
new Societe($db);
875 if ($modulepart ==
'invoice') {
876 include_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
877 $object_instance =
new Facture($db);
878 } elseif ($modulepart ==
'invoice_supplier') {
879 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.facture.class.php';
881 } elseif ($modulepart ==
'propal') {
882 include_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propal.class.php';
883 $object_instance =
new Propal($db);
884 } elseif ($modulepart ==
'order') {
885 include_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
886 $object_instance =
new Commande($db);
887 } elseif ($modulepart ==
'order_supplier') {
888 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
890 } elseif ($modulepart ==
'contract') {
891 include_once DOL_DOCUMENT_ROOT.
'/contrat/class/contrat.class.php';
892 $object_instance =
new Contrat($db);
893 } elseif ($modulepart ==
'tax') {
894 include_once DOL_DOCUMENT_ROOT.
'/compta/sociales/class/chargesociales.class.php';
898 foreach ($filearray as $key => $file) {
899 if (!is_dir($file[
'name'])
900 && $file[
'name'] !=
'.'
901 && $file[
'name'] !=
'..'
902 && $file[
'name'] !=
'CVS'
905 $relativefile = preg_replace(
'/'.preg_quote($upload_dir.
'/',
'/').
'/',
'', $file[
'fullname']);
910 $object_instance->id = 0;
911 $object_instance->ref =
'';
915 if ($modulepart ==
'invoice') {
916 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
919 if ($modulepart ==
'invoice_supplier') {
920 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg);
921 $id = empty($reg[1]) ?
'' : $reg[1];
923 if ($modulepart ==
'propal') {
924 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
927 if ($modulepart ==
'order') {
928 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
931 if ($modulepart ==
'order_supplier') {
932 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
935 if ($modulepart ==
'contract') {
936 preg_match(
'/(.*)\/[^\/]+$/', $relativefile, $reg);
939 if ($modulepart ==
'tax') {
940 preg_match(
'/(\d+)\/[^\/]+$/', $relativefile, $reg);
944 if ((
$id || $ref) && $object_instance !==
null) {
946 $result = $object_instance->fetch(
$id, $ref);
950 print
'<tr><td colspan="2">';
951 print
'Delete orphelins file '.$file[
'fullname'].
'<br>';
952 if (
GETPOST(
'clean_orphelin_dir',
'alpha') ==
'confirmed') {
957 } elseif ($result < 0) {
958 print
'Error in '.get_class($object_instance).
'.fetch of id'.
$id.
' ref='.$ref.
', result='.$result.
'<br>';
968if ($ok &&
GETPOST(
'clean_product_stock_batch',
'alpha')) {
969 $methodtofix =
GETPOST(
'methodtofix',
'alpha') ?
GETPOST(
'methodtofix',
'alpha') :
'updatestock';
971 print
'<tr><td colspan="2"><br>*** Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
973 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
974 $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";
975 $sql .=
" WHERE p.rowid = ps.fk_product";
976 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
977 $sql .=
" HAVING (SUM(pb.qty) IS NOT NULL AND reel != SUM(pb.qty)) OR (SUM(pb.qty) IS NULL AND p.tobatch > 0)";
979 $resql = $db->query($sql);
981 $num = $db->num_rows($resql);
986 $obj = $db->fetch_object($resql);
987 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)';
990 if ($obj->reel != $obj->reelbatch) {
991 if (empty($obj->tobatch)) {
993 print
' -> Delete qty '.$obj->reelbatch.
' for any lot linked to fk_product_stock='.$obj->psrowid;
994 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"product_batch";
995 $sql2 .=
" WHERE fk_product_stock = ".((int) $obj->psrowid);
998 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
999 $resql2 = $db->query($sql2);
1006 if ($methodtofix ==
'updatebatch') {
1008 print
' -> Insert qty '.($obj->reel - $obj->reelbatch).
' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
1009 $sql2 =
"INSERT INTO ".MAIN_DB_PREFIX.
"product_batch(fk_product_stock, batch, qty)";
1010 $sql2 .=
"VALUES(".((int) $obj->psrowid).
", '000000', ".((float) ($obj->reel - $obj->reelbatch)).
")";
1013 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
1014 $resql2 = $db->query($sql2);
1023 if ($methodtofix ==
'updatestock') {
1025 print
' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((float) $obj->reelbatch) :
'0').
' for ps.rowid = '.((
int) $obj->psrowid);
1026 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"product_stock";
1027 $sql2 .=
" SET reel = ".($obj->reelbatch ? ((float) $obj->reelbatch) :
'0').
" WHERE rowid = ".((
int) $obj->psrowid);
1030 if (
GETPOST(
'clean_product_stock_batch') ==
'confirmed') {
1035 $resql2 = $db->query($sql2);
1038 $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)';
1039 $resql3 = $db->query($sql3);
1064 print
'<tr><td colspan="2">Nothing to do</td></tr>';
1073if ($ok &&
GETPOST(
'clean_product_stock_negative_if_batch',
'alpha')) {
1074 print
'<tr><td colspan="2"><br>Clean table product_batch, methodtofix='.$methodtofix.
' (possible values: updatestock or updatebatch)</td></tr>';
1076 $sql =
"SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
1077 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product as p, ".MAIN_DB_PREFIX.
"product_stock as ps, ".MAIN_DB_PREFIX.
"product_batch as pb";
1078 $sql .=
" WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
1079 $sql .=
" AND p.tobatch > 0";
1080 $sql .=
" GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
1081 $sql .=
" HAVING reel != SUM(pb.qty)";
1082 $resql = $db->query($sql);
1084 $num = $db->num_rows($resql);
1089 $obj = $db->fetch_object($resql);
1090 print
'<tr><td>'.$obj->rowid.
'-'.$obj->ref.
'-'.$obj->fk_entrepot.
' -> '.$obj->psrowid.
': '.$obj->reel.
' != '.$obj->reelbatch;
1099if ($ok &&
GETPOST(
'set_empty_time_spent_amount',
'alpha')) {
1100 print
'<tr><td colspan="2"><br>*** Set value of time spent without amount</td></tr>';
1102 $sql =
"SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm";
1103 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"user as u";
1104 $sql .=
" WHERE ptt.fk_user = u.rowid";
1105 $sql .=
" AND ptt.thm IS NULL and u.thm > 0";
1106 $sql .=
" GROUP BY u.rowid, u.login, u.thm";
1108 $resql = $db->query($sql);
1110 $num = $db->num_rows($resql);
1115 $obj = $db->fetch_object($resql);
1116 print
'<tr><td>'.$obj->login.
'-'.$obj->user_id.
' ('.$obj->nb.
' lines to fix) -> '.$obj->user_thm;
1120 if (
GETPOST(
'set_empty_time_spent_amount') ==
'confirmed') {
1121 $sql2 =
"UPDATE ".MAIN_DB_PREFIX.
"element_time";
1122 $sql2 .=
" SET thm = ".$obj->user_thm.
" WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id);
1123 $resql2 = $db->query($sql2);
1145 print
'<tr><td>No time spent with empty line on users with a hourly rate defined</td></tr>';
1154if ($ok &&
GETPOST(
'force_disable_of_modules_not_found',
'alpha')) {
1155 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>';
1157 $arraylistofkey = array(
'hooks',
'js',
'css');
1159 foreach ($arraylistofkey as $key) {
1160 $sql =
"SELECT DISTINCT name, value";
1161 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const as c";
1162 $sql .=
" WHERE name LIKE 'MAIN_MODULE_%_".strtoupper($db->escape($key)).
"'";
1163 $sql .=
" ORDER BY name";
1165 $resql = $db->query($sql);
1167 $num = $db->num_rows($resql);
1171 $obj = $db->fetch_object($resql);
1172 $constantname = $obj->name;
1180 if (preg_match(
'/MAIN_MODULE_(.*)_'.strtoupper($key).
'/i', $constantname, $reg)) {
1181 $name = strtolower($reg[1]);
1187 if ($key ==
'hooks') {
1188 $reloffile = $name.
'/class/actions_'.$name.
'.class.php';
1191 $value = $obj->value;
1192 $valuearray = (array) json_decode($value);
1193 $reloffile = $valuearray[0];
1194 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1196 if ($key ==
'css') {
1197 $value = $obj->value;
1198 $valuearray = (array) json_decode($value);
1199 if ($value && (!is_array($valuearray) || count($valuearray) == 0)) {
1200 $valuearray = array();
1201 $valuearray[0] = $value;
1203 $reloffile = preg_replace(
'/^\//',
'', $valuearray[0]);
1218 print
' - File of '.$key.
' ('.$reloffile.
') NOT found, we disable the module.';
1219 if (
GETPOST(
'force_disable_of_modules_not_found') ==
'confirmed') {
1220 $sql2 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"_".strtoupper($key).
"'";
1221 $resql2 = $db->query($sql2);
1226 $sql3 =
"DELETE FROM ".MAIN_DB_PREFIX.
"const WHERE name = 'MAIN_MODULE_".strtoupper($name).
"'";
1227 $resql3 = $db->query($sql3);
1232 print
' - <span class="warning">Cleaned</span>';
1235 print
' - <span class="warning">Canceled (test mode)</span>';
1238 print
' - File of '.$key.
' ('.$reloffile.
') found, we do nothing.';
1258 print
'<tr><td>No active module with missing files found by searching on MAIN_MODULE_(.*)_'.strtoupper($key).
'</td></tr>';
1268if ($ok &&
GETPOST(
'clean_perm_table',
'alpha')) {
1269 print
'<tr><td colspan="2"><br>*** Clean table user_rights from lines of external modules no more enabled</td></tr>';
1272 foreach (
$conf->modules as $key => $val) {
1273 $listofmods .= ($listofmods ?
',' :
'').
"'".$db->escape($val).
"'";
1276 $sql =
"SELECT id, libelle as label, module from ".MAIN_DB_PREFIX.
"rights_def WHERE module NOT IN (".$db->sanitize($listofmods, 1).
") AND id > 100000";
1278 $resql = $db->query($sql);
1280 $num = $db->num_rows($resql);
1284 $obj = $db->fetch_object($resql);
1286 print
'<tr><td>Found line with id '.$obj->id.
', label "'.$obj->label.
'" of module "'.$obj->module.
'" to delete';
1287 if (
GETPOST(
'clean_perm_table',
'alpha') ==
'confirmed') {
1288 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def WHERE id = ".((int) $obj->id);
1289 $resqldelete = $db->query($sqldelete);
1290 if (!$resqldelete) {
1300 print
'<tr><td>No lines of a disabled external module (with id > 100000) found into table rights_def</td></tr>';
1309if ($ok &&
GETPOST(
'clean_ecm_files_table',
'alpha')) {
1310 print
'<tr><td colspan="2"><br>*** Clean table ecm_files from lines of entries whose physical files does not exists anymore (emplemented for entity 1 only)</td></tr>';
1314 $sql =
"SELECT rowid, filename, filepath, entity from ".MAIN_DB_PREFIX.
"ecm_files";
1315 $sql .=
" WHERE entity = 1";
1316 $sql .=
" ORDER BY rowid ASC";
1319 $nbfiletodelete = 0;
1321 $resql = $db->query($sql);
1323 $num = $db->num_rows($resql);
1327 $obj = $db->fetch_object($resql);
1328 if ($obj->rowid > 0) {
1329 $filetocheck = DOL_DATA_ROOT.
'/'.$obj->filepath.
'/'.$obj->filename;
1333 if ($nbfiletodelete <= $MAXTODELETE) {
1334 print
'<tr><td>Found line with id '.$obj->rowid.
', entity '.$obj->entity.
', file "'.$filetocheck.
'" to delete';
1335 if (
GETPOST(
'clean_ecm_files_table',
'alpha') ==
'confirmed') {
1336 $sqldelete =
"DELETE FROM ".MAIN_DB_PREFIX.
"ecm_files WHERE rowid = ".((int) $obj->rowid);
1337 $resqldelete = $db->query($sqldelete);
1338 if (!$resqldelete) {
1352 if ($nbfiletodelete > $MAXTODELETE) {
1353 print
'<tr><td>There is more than '.$MAXTODELETE.
' invalid entries into ecm_files index table (among '.$nbfile.
' analyzed) with no valid physical files. Run the page several time to process all of them.</td></tr>';
1355 print
'<tr><td>Nb of entries processed into ecm_files index table: '.$nbfile.
', number of invalid record: '.$nbfiletodelete.
'</td></tr>';
1363if ($ok &&
GETPOST(
'force_utf8_on_tables',
'alpha')) {
1364 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>';
1366 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1367 $force_utf8_on_tables =
GETPOST(
'force_utf8_on_tables',
'alpha');
1369 $listoftables = $db->DDLListTablesFull($db->database_name);
1372 if ($force_utf8_on_tables ==
'confirmed') {
1373 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1374 print
'<!-- '.$sql.
' -->';
1375 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1376 $resql = $db->query($sql);
1379 $foreignkeystorestore = array();
1382 foreach ($listoftables as $table) {
1384 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1387 if ($table[1] ==
'VIEW') {
1388 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1393 $arrayofforeignkey = array(
1394 'llx_accounting_account' =>
'fk_accounting_account_fk_pcg_version',
1395 'llx_accounting_system' =>
'fk_accounting_account_fk_pcg_version',
1396 'llx_c_type_contact' =>
'fk_societe_commerciaux_fk_c_type_contact_code',
1397 'llx_societe_commerciaux' =>
'fk_societe_commerciaux_fk_c_type_contact_code'
1400 foreach ($arrayofforeignkey as $tmptable => $foreignkeyname) {
1401 if ($table[0] == $tmptable) {
1402 print
'<tr><td colspan="2">';
1403 $sqltmp =
"ALTER TABLE ".$db->sanitize($table[0]).
" DROP FOREIGN KEY ".$db->sanitize($foreignkeyname);
1405 if ($force_utf8_on_tables ==
'confirmed') {
1406 $resqltmp = $db->query($sqltmp);
1408 print
' - <span class="opacitymedium">Disabled</span>';
1411 $foreignkeystorestore[$tmptable] = $foreignkeyname;
1416 foreach ($listoftables as $table) {
1418 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1421 if ($table[1] ==
'VIEW') {
1422 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1426 $collation =
'utf8_unicode_ci';
1427 $defaultcollation = $db->getDefaultCollationDatabase();
1428 if (preg_match(
'/general/', $defaultcollation)) {
1429 $collation =
'utf8_general_ci';
1432 print
'<tr><td colspan="2">';
1434 $sql1 =
"ALTER TABLE ".$db->sanitize($table[0]).
" ROW_FORMAT=dynamic";
1435 $sql2 =
"ALTER TABLE ".$db->sanitize($table[0]).
" CONVERT TO CHARACTER SET utf8 COLLATE ".$db->sanitize($collation);
1436 print
'<!-- '.$sql1.
' -->';
1437 print
'<!-- '.$sql2.
' -->';
1438 if ($force_utf8_on_tables ==
'confirmed') {
1439 $resql1 = $db->query($sql1);
1441 $resql2 = $db->query($sql2);
1445 print
' - Done '.(($resql1 && $resql2) ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.
dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1447 print
' - <span class="opacitymedium">Disabled</span>';
1455 foreach ($foreignkeystorestore as $tmptable => $foreignkeyname) {
1456 $stringtofindinline =
"ALTER TABLE .* ADD CONSTRAINT ".$db->sanitize($foreignkeyname);
1457 $fileforkeys = DOL_DOCUMENT_ROOT.
'/install/mysql/tables/'.$tmptable.
'.key.sql';
1460 $handle = fopen($fileforkeys,
'r');
1462 while (($line = fgets($handle)) !==
false) {
1464 if (preg_match(
'/^'.$stringtofindinline.
'/i', $line)) {
1465 $resqltmp = $db->query($line);
1466 print
'<tr><td colspan="2">';
1468 print
' - Done '.($resqltmp ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1480 if ($force_utf8_on_tables ==
'confirmed') {
1481 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1482 print
'<!-- '.$sql.
' -->';
1483 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1484 $resql = $db->query($sql);
1487 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1492if ($ok &&
GETPOST(
'force_utf8mb4_on_tables',
'alpha')) {
1493 print
'<tr><td colspan="2"><br>*** Force page code and collation of tables into utf8mb4/utf8mb4_unicode_ci (for mysql/mariadb only)</td></tr>';
1495 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1496 $force_utf8mb4_on_tables =
GETPOST(
'force_utf8mb4_on_tables',
'alpha');
1499 $listoftables = $db->DDLListTablesFull($db->database_name);
1502 if ($force_utf8mb4_on_tables ==
'confirmed') {
1503 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1504 print
'<!-- '.$sql.
' -->';
1505 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1506 $resql = $db->query($sql);
1509 $foreignkeystorestore = array();
1512 foreach ($listoftables as $table) {
1514 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1517 if ($table[1] ==
'VIEW') {
1518 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1523 $arrayofforeignkey = array(
1524 'llx_accounting_account' =>
'fk_accounting_account_fk_pcg_version',
1525 'llx_accounting_system' =>
'fk_accounting_account_fk_pcg_version',
1526 'llx_c_type_contact' =>
'fk_societe_commerciaux_fk_c_type_contact_code',
1527 'llx_societe_commerciaux' =>
'fk_societe_commerciaux_fk_c_type_contact_code'
1530 foreach ($arrayofforeignkey as $tmptable => $foreignkeyname) {
1531 if ($table[0] == $tmptable) {
1532 print
'<tr><td colspan="2">';
1533 $sqltmp =
"ALTER TABLE ".$db->sanitize($table[0]).
" DROP FOREIGN KEY ".$db->sanitize($foreignkeyname);
1535 if ($force_utf8mb4_on_tables ==
'confirmed') {
1536 $resqltmp = $db->query($sqltmp);
1538 print
' - <span class="opacitymedium">Disabled</span>';
1541 $foreignkeystorestore[$tmptable] = $foreignkeyname;
1546 foreach ($listoftables as $table) {
1548 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1551 if ($table[1] ==
'VIEW') {
1552 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' <span class="opacitymedium">(Skipped)</span></td></tr>';
1556 $collation =
'utf8mb4_unicode_ci';
1557 $defaultcollation = $db->getDefaultCollationDatabase();
1558 if (preg_match(
'/general/', $defaultcollation)) {
1559 $collation =
'utf8mb4_general_ci';
1562 print
'<tr><td colspan="2">';
1564 $sql1 =
"ALTER TABLE ".$db->sanitize($table[0]).
" ROW_FORMAT=dynamic";
1565 $sql2 =
"ALTER TABLE ".$db->sanitize($table[0]).
" CONVERT TO CHARACTER SET utf8mb4 COLLATE ".$db->sanitize($collation);
1566 print
'<!-- '.$sql1.
' -->';
1567 print
'<!-- '.$sql2.
' -->';
1568 if ($force_utf8mb4_on_tables ==
'confirmed') {
1569 $resql1 = $db->query($sql1);
1571 $resql2 = $db->query($sql2);
1575 print
' - Done '.(($resql1 && $resql2) ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.
dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1577 print
' - <span class="opacitymedium">Disabled</span>';
1585 foreach ($foreignkeystorestore as $tmptable => $foreignkeyname) {
1586 $stringtofindinline =
"ALTER TABLE .* ADD CONSTRAINT ".$db->sanitize($foreignkeyname);
1587 $fileforkeys = DOL_DOCUMENT_ROOT.
'/install/mysql/tables/'.$tmptable.
'.key.sql';
1590 $handle = fopen($fileforkeys,
'r');
1592 while (($line = fgets($handle)) !==
false) {
1594 if (preg_match(
'/^'.$stringtofindinline.
'/i', $line)) {
1595 $resqltmp = $db->query($line);
1596 print
'<tr><td colspan="2">';
1598 print
' - Done '.($resqltmp ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1610 if ($force_utf8mb4_on_tables ==
'confirmed') {
1611 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1612 print
'<!-- '.$sql.
' -->';
1613 print
'<tr><td colspan="2">'.$sql.
'</td></tr>';
1614 $resql = $db->query($sql);
1617 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1621if ($ok &&
GETPOST(
'force_collation_from_conf_on_tables',
'alpha')) {
1622 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>';
1624 if ($db->type ==
"mysql" || $db->type ==
"mysqli") {
1625 $force_collation_from_conf_on_tables =
GETPOST(
'force_collation_from_conf_on_tables',
'alpha');
1627 $listoftables = $db->DDLListTablesFull($db->database_name);
1630 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1631 $sql =
'SET FOREIGN_KEY_CHECKS=0';
1632 print
'<!-- '.$sql.
' -->';
1633 $resql = $db->query($sql);
1636 foreach ($listoftables as $table) {
1638 if (
$conf->db->dolibarr_main_db_encryption != 0 && preg_match(
'/\_const$/', $table[0])) {
1641 if ($table[1] ==
'VIEW') {
1642 print
'<tr><td colspan="2">'.$table[0].
' is a '.$table[1].
' (Skipped)</td></tr>';
1646 print
'<tr><td colspan="2">';
1648 $sql1 =
"ALTER TABLE ".$table[0].
" ROW_FORMAT=dynamic";
1649 $sql2 =
"ALTER TABLE ".$table[0].
" CONVERT TO CHARACTER SET ".
$conf->db->character_set.
" COLLATE ".
$conf->db->dolibarr_main_db_collation;
1650 print
'<!-- '.$sql1.
' -->';
1651 print
'<!-- '.$sql2.
' -->';
1652 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1653 $resql1 = $db->query($sql1);
1655 $resql2 = $db->query($sql2);
1659 print
' - Done '.(($resql1 && $resql2) ?
'<span class="opacitymedium">(OK)</span>' :
'<span class="error" title="'.
dol_escape_htmltag($db->lasterror).
'">(KO)</span>');
1661 print
' - <span class="opacitymedium">Disabled</span>';
1667 if ($force_collation_from_conf_on_tables ==
'confirmed') {
1668 $sql =
'SET FOREIGN_KEY_CHECKS=1';
1669 print
'<!-- '.$sql.
' -->';
1670 $resql = $db->query($sql);
1673 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1678if ($ok &&
GETPOST(
'rebuild_sequences',
'alpha')) {
1679 print
'<tr><td colspan="2"><br>*** Force to rebuild sequences (for postgresql only)</td></tr>';
1681 if ($db->type ==
"pgsql") {
1682 $rebuild_sequence =
GETPOST(
'rebuild_sequences',
'alpha');
1684 if ($rebuild_sequence ==
'confirmed') {
1685 $sql =
"SELECT dol_util_rebuild_sequences();";
1686 print
'<!-- '.$sql.
' -->';
1687 $resql = $db->query($sql);
1690 print
'<tr><td colspan="2">Not available with database type '.$db->type.
'</td></tr>';
1695if ($ok &&
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines')) {
1719 $repair_link_dispatch_lines_supplier_order_lines =
GETPOST(
'repair_link_dispatch_lines_supplier_order_lines',
'alpha');
1722 echo
'<tr><th>Repair llx_receptiondet_batch.fk_commandefourndet</th></tr>';
1723 echo
'<tr><td>Repair in progress. This may take a while.</td></tr>';
1725 $sql_dispatch =
'SELECT * FROM '.MAIN_DB_PREFIX.
'receptiondet_batch WHERE COALESCE(fk_elementdet, 0) = 0';
1727 $resql_dispatch = $db->query($sql_dispatch);
1728 $n_processed_rows = 0;
1730 if ($resql_dispatch) {
1731 if ($db->num_rows($resql_dispatch) == 0) {
1732 echo
'<tr><td>Nothing to do.</td></tr>';
1735 while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
1736 $sql_line =
'SELECT line.rowid, line.qty FROM '.MAIN_DB_PREFIX.
'commande_fournisseurdet AS line';
1737 $sql_line .=
' WHERE line.fk_commande = '.((int) $obj_dispatch->fk_commande);
1738 $sql_line .=
' AND line.fk_product = '.((int) $obj_dispatch->fk_product);
1739 $resql_line = $db->query($sql_line);
1745 $remaining_qty = $obj_dispatch->qty;
1746 $first_iteration =
true;
1748 echo
'<tr><td>Unable to find a matching supplier order line for dispatch #'.$obj_dispatch->rowid.
'</td></tr>';
1749 $errors[] = $sql_line;
1750 $n_processed_rows++;
1753 if ($db->num_rows($resql_line) == 0) {
1756 while ($obj_line = $db->fetch_object($resql_line)) {
1757 if (!$remaining_qty) {
1760 if (!$obj_line->rowid) {
1763 $qty_for_line = min($remaining_qty, $obj_line->qty);
1764 if ($first_iteration) {
1765 $sql_attach =
'UPDATE '.MAIN_DB_PREFIX.
'receptiondet_batch';
1766 $sql_attach .=
' SET fk_elementdet = '.((int) $obj_line->rowid).
', qty = '.((float) $qty_for_line);
1767 $sql_attach .=
' WHERE rowid = '.((int) $obj_dispatch->rowid);
1768 $first_iteration =
false;
1770 $sql_attach_values = array(
1771 (
string) ((
int) $obj_dispatch->fk_element),
1772 (
string) ((
int) $obj_dispatch->fk_product),
1773 (
string) ((
int) $obj_line->rowid),
1774 (
string) ((
float) $qty_for_line),
1775 (
string) ((
int) $obj_dispatch->fk_entrepot),
1776 (
string) ((
int) $obj_dispatch->fk_user),
1777 $obj_dispatch->datec ?
"'".$db->idate($db->jdate($obj_dispatch->datec)).
"'" :
'NULL',
1778 $obj_dispatch->comment ?
"'".$db->escape($obj_dispatch->comment).
"'" :
'NULL',
1779 $obj_dispatch->
status ? (string) ((int) $obj_dispatch->
status) :
'NULL',
1780 $obj_dispatch->tms ?
"'".$db->idate($db->jdate($obj_dispatch->tms)).
"'" :
'NULL',
1781 $obj_dispatch->batch ?
"'".$db->escape($obj_dispatch->batch).
"'" :
'NULL',
1782 $obj_dispatch->eatby ?
"'".$db->escape($obj_dispatch->eatby).
"'" :
'NULL',
1783 $obj_dispatch->sellby ?
"'".$db->escape($obj_dispatch->sellby).
"'" :
'NULL'
1785 $sql_attach_values = implode(
', ', $sql_attach_values);
1787 $sql_attach =
'INSERT INTO '.MAIN_DB_PREFIX.
'receptiondet_batch';
1788 $sql_attach .=
' (fk_element, fk_product, fk_elementdet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)';
1789 $sql_attach .=
" VALUES (".$sql_attach_values.
")";
1792 if ($repair_link_dispatch_lines_supplier_order_lines ==
'confirmed') {
1793 $resql_attach = $db->query($sql_attach);
1795 $resql_attach =
true;
1798 if ($resql_attach) {
1799 $remaining_qty -= $qty_for_line;
1801 $errors[] = $sql_attach;
1804 $first_iteration =
false;
1806 $n_processed_rows++;
1809 if (!($n_processed_rows & 0xff)) {
1810 echo
'<tr><td>Processed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1816 echo
'<tr><td>Unable to find any dispatch without an fk_commandefourndet.'.
"</td></tr>\n";
1817 echo $sql_dispatch.
"\n";
1819 echo
'<tr><td>Fixed '.$n_processed_rows.
' rows with '.count($errors).
' errors…'.
"</td></tr>\n";
1820 echo
'<tr><td>DONE.'.
"</td></tr>\n";
1822 if (count($errors)) {
1824 echo
'<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
1830 echo
'<tr><td><h3>SQL queries with errors:</h3></tr></td>';
1831 echo
'<tr><td>'.implode(
'</td></tr><tr><td>', $errors).
'</td></tr>';
1835if ($ok &&
GETPOST(
'repair_supplier_order_duplicate_ref')) {
1836 require_once DOL_DOCUMENT_ROOT .
'/fourn/class/fournisseur.commande.class.php';
1837 include_once DOL_DOCUMENT_ROOT .
'/societe/class/societe.class.php';
1844 $sql =
"SELECT * FROM " . MAIN_DB_PREFIX .
"commande_fournisseur";
1845 $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)";
1848 $duplicateSupplierOrders = [];
1849 $resql = $db->query($sql);
1851 while ($rawSupplierOrder = $db->fetch_object($resql)) {
1853 $supplierOrder->setVarsFromFetchObj($rawSupplierOrder);
1855 $duplicateSupplierOrders[$rawSupplierOrder->ref] [] = $supplierOrder;
1862 foreach ($duplicateSupplierOrders as $ref => $supplierOrders) {
1864 foreach (array_slice($supplierOrders, 1) as $supplierOrder) {
1867 $soc->fetch($supplierOrder->fourn_id);
1869 $newRef = $supplierOrder->getNextNumRef($soc);
1871 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"commande_fournisseur cf SET cf.ref = '" . $db->escape($newRef) .
"' WHERE cf.rowid = " . (int) $supplierOrder->id;
1872 if (!$db->query($sql)) {
1888if ($ok &&
GETPOST(
'recalculateinvoicetotal') ==
'confirmed') {
1891 $sql =
"SELECT f.rowid, SUM(fd.total_ht) as total_ht";
1892 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture f";
1893 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facturedet fd ON fd.fk_facture = f.rowid";
1894 $sql .=
" WHERE f.total_ht = 0";
1895 $sql .=
" GROUP BY fd.fk_facture HAVING SUM(fd.total_ht) <> 0";
1897 $resql = $db->query($sql);
1899 $num = $db->num_rows($resql);
1900 print
"We found ".$num.
" factures qualified that will have their total recalculated because they are at zero and line items not at zero\n";
1901 dol_syslog(
"We found ".$num.
" factures qualified that will have their total recalculated because they are at zero and line items not at zero");
1906 $obj = $db->fetch_object($resql);
1909 SUM(fd.total_ht) as 'total_ht',
1910 SUM(fd.total_tva) as 'total_tva',
1911 SUM(fd.total_localtax1) as 'localtax1',
1912 SUM(fd.total_localtax2) as 'localtax2',
1913 SUM(fd.total_ttc) as 'total_ttc'
1915 ".MAIN_DB_PREFIX.
"facturedet fd
1917 fd.fk_facture = $obj->rowid";
1918 $ressql_calculs = $db->query($sql_calculs);
1919 while ($obj_calcul = $db->fetch_object($ressql_calculs)) {
1921 UPDATE ".MAIN_DB_PREFIX.
"facture
1923 total_ht = ".($obj_calcul->total_ht ?
price2num($obj_calcul->total_ht,
'MT') : 0).
",
1924 total_tva = ".($obj_calcul->total_tva ?
price2num($obj_calcul->total_tva,
'MT') : 0).
",
1925 localtax1 = ".($obj_calcul->localtax1 ?
price2num($obj_calcul->localtax1,
'MT') : 0).
",
1926 localtax2 = ".($obj_calcul->localtax2 ?
price2num($obj_calcul->localtax2,
'MT') : 0).
",
1927 total_ttc = ".($obj_calcul->total_ttc ?
price2num($obj_calcul->total_ttc,
'MT') : 0).
"
1929 rowid = $obj->rowid";
1930 $db->query($sql_maj);
1935 print
"Pas de factures à traiter\n";
1939 dol_syslog(
"calculate_total_and_taxes.php: Error");
1952if (empty($actiondone)) {
1953 print
'<div class="error">'.$langs->trans(
"ErrorWrongParameters").
'</div>';
1957 print
'<div class="center" style="padding-top: 10px"><a href="../index.php?mainmenu=home&leftmenu=home'.(GETPOSTISSET(
"login") ?
'&username='.urlencode(
GETPOST(
"login")) :
'').
'">';
1958 print $langs->trans(
"GoToDolibarr");
1965if ($db->connected) {
1970if (!$ok && isset($argv[1])) {
$id
Support class for third parties, contacts, members, users or resources.
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.
dolDecrypt($chain, $key='')
Decode a string with a symmetric encryption.