88 public $module_position =
'50';
105 public $dirs = array();
110 public $boxes = array();
115 public $const = array();
120 public $cronjobs = array();
130 public $rights_class;
135 public $menu = array();
164 public $module_parts = array();
176 public $dbversion =
"-";
220 public $descriptionlong;
233 public $export_label;
235 public $export_permission;
236 public $export_fields_array;
237 public $export_TypeFields_array;
238 public $export_entities_array;
239 public $export_special_array;
240 public $export_dependencies_array;
241 public $export_sql_start;
242 public $export_sql_end;
243 public $export_sql_order;
256 public $import_label;
267 public $always_enabled;
277 public $core_enabled;
293 public $config_page_url;
312 public $conflictwith;
324 public $warnings_activation;
331 public $warnings_activation_ext;
344 public $need_dolibarr_version;
349 public $hidden =
false;
354 public $url_last_version;
383 protected function _init($array_sql, $options =
'')
407 if (!$err && !preg_match(
'/newboxdefonly/', $options)) {
412 if (!$err && !preg_match(
'/noboxes/', $options)) {
437 $num = count($array_sql);
438 for ($i = 0; $i < $num; $i++) {
440 $val = $array_sql[$i];
443 if (is_array($val)) {
445 $ignoreerror = $val[
'ignoreerror'];
448 $sql = str_replace(
'__ENTITY__', $conf->entity, $sql);
450 dol_syslog(get_class($this).
"::_init ignoreerror=".$ignoreerror.
"", LOG_DEBUG);
451 $result = $this->
db->query($sql, $ignoreerror);
454 $this->error = $this->
db->lasterror();
457 dol_syslog(get_class($this).
"::_init Warning ".$this->
db->lasterror(), LOG_WARNING);
468 $this->
db->rollback();
482 protected function _remove($array_sql, $options =
'')
510 if (!$err && !preg_match(
'/(newboxdefonly|noboxes)/', $options)) {
535 $num = count($array_sql);
536 for ($i = 0; $i < $num; $i++) {
538 dol_syslog(get_class($this).
"::_remove", LOG_DEBUG);
539 $result = $this->
db->query($array_sql[$i]);
541 $this->error = $this->
db->error();
552 $this->
db->rollback();
567 $langs->load(
"admin");
569 if ($langs->transnoentitiesnoconv(
"Module".$this->numero.
"Name") != (
"Module".$this->numero.
"Name")) {
571 return $langs->transnoentitiesnoconv(
"Module".$this->numero.
"Name");
574 if (is_array($this->langfiles)) {
575 foreach ($this->langfiles as $val) {
582 if ($langs->trans(
"Module".$this->name.
"Name") != (
"Module".$this->name.
"Name")) {
584 return $langs->transnoentitiesnoconv(
"Module".$this->
name.
"Name");
588 return $langs->transnoentitiesnoconv($this->
name);
601 $langs->load(
"admin");
603 if ($langs->transnoentitiesnoconv(
"Module".$this->numero.
"Desc") != (
"Module".$this->numero.
"Desc")) {
605 return $langs->transnoentitiesnoconv(
"Module".$this->numero.
"Desc");
608 if (is_array($this->langfiles)) {
609 foreach ($this->langfiles as $val) {
616 if ($langs->transnoentitiesnoconv(
"Module".$this->name.
"Desc") != (
"Module".$this->name.
"Desc")) {
618 return $langs->trans(
"Module".$this->
name.
"Desc");
635 $langs->load(
"admin");
637 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
638 include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
644 $content = file_get_contents($pathoffile);
646 if ((
float) DOL_VERSION >= 6.0) {
647 @include_once DOL_DOCUMENT_ROOT.
'/core/lib/parsemd.lib.php';
659 $content = nl2br($content);
663 if (!empty($this->descriptionlong)) {
664 if (is_array($this->langfiles)) {
665 foreach ($this->langfiles as $val) {
672 $content = $langs->transnoentitiesnoconv($this->descriptionlong);
692 $pathoffile =
dol_buildpath(strtolower($this->
name).
'/README-'.$langs->defaultlang.
'.md', 0);
697 $tmp = explode(
'_', $langs->defaultlang);
698 $pathoffile =
dol_buildpath(strtolower($this->
name).
'/README-'.$tmp[0].
'.md', 0);
710 return ($filefound ? $pathoffile :
'');
722 $langs->load(
"admin");
724 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
725 include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
731 $pathoffile =
dol_buildpath(strtolower($this->
name).
'/ChangeLog-'.$langs->defaultlang.
'.md', 0);
743 $content = file_get_contents($pathoffile);
745 if ((
float) DOL_VERSION >= 6.0) {
746 @include_once DOL_DOCUMENT_ROOT.
'/core/lib/parsemd.lib.php';
749 $content = nl2br($content);
763 return $this->editor_name;
773 return $this->editor_url;
787 $langs->load(
"admin");
791 $newversion = preg_replace(
'/_deprecated/',
'', $this->version);
792 if ($newversion ==
'experimental') {
793 $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionExperimental") : $newversion);
794 } elseif ($newversion ==
'development') {
795 $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionDevelopment") : $newversion);
796 } elseif ($newversion ==
'dolibarr') {
798 } elseif ($newversion) {
801 $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionUnknown") :
'unknown');
804 if (preg_match(
'/_deprecated/', $this->version)) {
805 $ret .= ($translated ?
' ('.$langs->transnoentitiesnoconv(
"Deprecated").
')' : $this->version);
817 if (in_array($this->version, array(
'dolibarr',
'experimental',
'development'))) {
818 return $this->module_position;
820 if ($this->module_position >= 100000) {
821 return $this->module_position;
823 return $this->module_position + 100000;
837 if ($this->version ==
'dolibarr' || $this->version ==
'dolibarr_deprecated') {
840 if (!empty($this->version) && !in_array($this->version, array(
'experimental',
'development'))) {
843 if (!empty($this->editor_name) || !empty($this->editor_url)) {
846 if ($this->numero >= 100000) {
860 return $this->langfiles;
874 $langstring =
"ExportDataset_".$this->export_code[$r];
875 if ($langs->trans($langstring) == $langstring) {
877 return $langs->trans($this->export_label[$r]);
880 return $langs->trans($langstring);
896 $langstring =
"ImportDataset_".$this->import_code[$r];
898 if ($langs->trans($langstring) == $langstring) {
900 return $langs->transnoentitiesnoconv($this->import_label[$r]);
903 return $langs->transnoentitiesnoconv($langstring);
919 $sql =
"SELECT tms FROM ".MAIN_DB_PREFIX.
"const";
920 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
921 $sql .=
" AND entity IN (0, ".$conf->entity.
")";
923 dol_syslog(get_class($this).
"::getLastActiveDate", LOG_DEBUG);
928 $obj = $this->
db->fetch_object(
$resql);
930 return $this->
db->jdate($obj->tms);
949 $sql =
"SELECT tms, note FROM ".MAIN_DB_PREFIX.
"const";
950 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
951 $sql .=
" AND entity IN (0, ".$conf->entity.
")";
953 dol_syslog(get_class($this).
"::getLastActiveDate", LOG_DEBUG);
958 $obj = $this->
db->fetch_object(
$resql);
962 $tmp = json_decode($obj->note,
true);
965 'authorid' => $tmp[
'authorid'],
967 'lastactivationdate' => $this->
db->jdate($obj->tms),
968 'lastactivationversion' => (!empty($tmp[
'lastactivationversion']) ? $tmp[
'lastactivationversion'] :
'unknown'),
991 $entity = ((!empty($this->always_enabled) || !empty($this->core_enabled)) ? 0 : $conf->entity);
993 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
994 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
995 $sql .=
" AND entity IN (0, ".$entity.
")";
997 dol_syslog(get_class($this).
"::_active delete activation constant", LOG_DEBUG);
1003 $note = json_encode(
1005 'authorid' => (is_object($user) ? $user->id : 0),
1006 'ip' => (empty($_SERVER[
'REMOTE_ADDR']) ?
'' : $_SERVER[
'REMOTE_ADDR']),
1007 'lastactivationversion' => $this->version,
1011 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name, value, visible, entity, note) VALUES";
1012 $sql .=
" (".$this->db->encrypt($this->const_name);
1013 $sql .=
", ".$this->db->encrypt(
'1');
1014 $sql .=
", 0, ".((int) $entity);
1015 $sql .=
", '".$this->db->escape($note).
"')";
1017 dol_syslog(get_class($this).
"::_active insert activation constant", LOG_DEBUG);
1041 $entity = ((!empty($this->always_enabled) || !empty($this->core_enabled)) ? 0 : $conf->entity);
1043 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
1044 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
1045 $sql .=
" AND entity IN (0, ".$entity.
")";
1047 dol_syslog(get_class($this).
"::_unactive", LOG_DEBUG);
1048 $this->
db->query($sql);
1078 if (empty($reldir)) {
1082 include_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
1085 foreach ($conf->file->dol_document_root as $dirroot) {
1087 $dirsql = $dirroot.$reldir;
1091 $listofsubdir = array(
'',
'tables/',
'data/');
1092 if ($this->
db->type ==
'pgsql') {
1093 $listofsubdir[] =
'../pgsql/functions/';
1096 foreach ($listofsubdir as $subdir) {
1097 $dir = $dirsql.$subdir;
1099 $handle = @opendir($dir);
1100 if (is_resource($handle)) {
1105 while (($file = readdir($handle)) !==
false) {
1109 foreach ($files as $file) {
1110 if ($onlywithsuffix) {
1111 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1118 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) ==
'llx_') {
1119 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1130 while (($file = readdir($handle)) !==
false) {
1134 foreach ($files as $file) {
1135 if ($onlywithsuffix) {
1136 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1143 if (preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) ==
'llx_') {
1144 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1155 while (($file = readdir($handle)) !==
false) {
1159 foreach ($files as $file) {
1160 if ($onlywithsuffix) {
1161 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1168 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 9) ==
'functions') {
1169 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1180 while (($file = readdir($handle)) !==
false) {
1184 foreach ($files as $file) {
1185 if ($onlywithsuffix) {
1186 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1193 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) ==
'data') {
1194 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1205 while (($file = readdir($handle)) !==
false) {
1209 foreach ($files as $file) {
1210 if ($onlywithsuffix) {
1211 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1218 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 6) ==
'update') {
1219 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1237 dol_syslog(
"A module ask to load sql files into ".$reldir.
" but this directory was not found.", LOG_WARNING);
1254 include_once DOL_DOCUMENT_ROOT.
'/core/class/infobox.class.php';
1260 if (is_array($this->boxes)) {
1261 dol_syslog(get_class($this).
"::insert_boxes", LOG_DEBUG);
1265 foreach ($this->boxes as $key => $value) {
1266 $file = isset($this->boxes[$key][
'file']) ? $this->boxes[$key][
'file'] :
'';
1267 $note = isset($this->boxes[$key][
'note']) ? $this->boxes[$key][
'note'] :
'';
1268 $enabledbydefaulton = isset($this->boxes[$key][
'enabledbydefaulton']) ? $this->boxes[$key][
'enabledbydefaulton'] :
'Home';
1271 $file = isset($this->boxes[$key][1]) ? $this->boxes[$key][1] :
'';
1274 $note = isset($this->boxes[$key][2]) ? $this->boxes[$key][2] :
'';
1278 $sql =
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"boxes_def";
1279 $sql .=
" WHERE file = '".$this->db->escape($file).
"'";
1280 $sql .=
" AND entity = ".$conf->entity;
1282 $sql .=
" AND note ='".$this->db->escape($note).
"'";
1285 $result = $this->
db->query($sql);
1287 $obj = $this->
db->fetch_object($result);
1288 if ($obj->nb == 0) {
1292 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"boxes_def (file, entity, note)";
1293 $sql .=
" VALUES ('".$this->db->escape($file).
"', ";
1294 $sql .= $conf->entity.
", ";
1295 $sql .= $note ?
"'".$this->db->escape($note).
"'" :
"null";
1298 dol_syslog(get_class($this).
"::insert_boxes", LOG_DEBUG);
1304 if (!$err && !preg_match(
'/newboxdefonly/', $option)) {
1305 $lastid = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"boxes_def",
"rowid");
1307 foreach ($pos_name as $key2 => $val2) {
1309 if ($enabledbydefaulton && $val2 != $enabledbydefaulton) {
1313 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"boxes (box_id, position, box_order, fk_user, entity)";
1314 $sql .=
" VALUES (".((int) $lastid).
", ".((int) $key2).
", '0', 0, ".((int) $conf->entity).
")";
1316 dol_syslog(get_class($this).
"::insert_boxes onto page ".$key2.
"=".$val2.
"", LOG_DEBUG);
1325 $this->
db->commit();
1327 $this->error = $this->
db->lasterror();
1328 $this->
db->rollback();
1333 $this->error = $this->
db->lasterror();
1356 if (is_array($this->boxes)) {
1357 foreach ($this->boxes as $key => $value) {
1359 if (empty($this->boxes[$key][
'file'])) {
1360 $file = isset($this->boxes[$key][1]) ? $this->boxes[$key][1] :
'';
1362 $file = $this->boxes[$key][
'file'];
1370 if ($file ==
'box_graph_product_distribution.php') {
1371 if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
1372 dol_syslog(
"We discard deleting module ".$file.
" because another module still active requires it.");
1377 if ($this->
db->type ==
'sqlite3') {
1380 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes ";
1381 $sql .=
"WHERE ".MAIN_DB_PREFIX.
"boxes.box_id IN (";
1382 $sql .=
"SELECT ".MAIN_DB_PREFIX.
"boxes_def.rowid ";
1383 $sql .=
"FROM ".MAIN_DB_PREFIX.
"boxes_def ";
1384 $sql .=
"WHERE ".MAIN_DB_PREFIX.
"boxes_def.file = '".$this->
db->escape($file).
"') ";
1385 $sql .=
"AND ".MAIN_DB_PREFIX.
"boxes.entity = ".$conf->entity;
1387 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes";
1388 $sql .=
" USING ".MAIN_DB_PREFIX.
"boxes, ".MAIN_DB_PREFIX.
"boxes_def";
1389 $sql .=
" WHERE ".MAIN_DB_PREFIX.
"boxes.box_id = ".MAIN_DB_PREFIX.
"boxes_def.rowid";
1390 $sql .=
" AND ".MAIN_DB_PREFIX.
"boxes_def.file = '".$this->
db->escape($file).
"'";
1391 $sql .=
" AND ".MAIN_DB_PREFIX.
"boxes.entity = ".$conf->entity;
1394 dol_syslog(get_class($this).
"::delete_boxes", LOG_DEBUG);
1397 $this->error = $this->
db->lasterror();
1401 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def";
1402 $sql .=
" WHERE file = '".$this->db->escape($file).
"'";
1403 $sql .=
" AND entity = ".$conf->entity;
1405 dol_syslog(get_class($this).
"::delete_boxes", LOG_DEBUG);
1408 $this->error = $this->
db->lasterror();
1426 include_once DOL_DOCUMENT_ROOT.
'/core/class/infobox.class.php';
1432 if (is_array($this->cronjobs)) {
1433 dol_syslog(get_class($this).
"::insert_cronjobs", LOG_DEBUG);
1435 foreach ($this->cronjobs as $key => $value) {
1436 $entity = isset($this->cronjobs[$key][
'entity']) ? $this->cronjobs[$key][
'entity'] : $conf->entity;
1437 $label = isset($this->cronjobs[$key][
'label']) ? $this->cronjobs[$key][
'label'] :
'';
1438 $jobtype = isset($this->cronjobs[$key][
'jobtype']) ? $this->cronjobs[$key][
'jobtype'] :
'';
1439 $class = isset($this->cronjobs[$key][
'class']) ? $this->cronjobs[$key][
'class'] :
'';
1440 $objectname = isset($this->cronjobs[$key][
'objectname']) ? $this->cronjobs[$key][
'objectname'] :
'';
1441 $method = isset($this->cronjobs[$key][
'method']) ? $this->cronjobs[$key][
'method'] :
'';
1442 $command = isset($this->cronjobs[$key][
'command']) ? $this->cronjobs[$key][
'command'] :
'';
1443 $parameters = isset($this->cronjobs[$key][
'parameters']) ? $this->cronjobs[$key][
'parameters'] :
'';
1444 $comment = isset($this->cronjobs[$key][
'comment']) ? $this->cronjobs[$key][
'comment'] :
'';
1445 $frequency = isset($this->cronjobs[$key][
'frequency']) ? $this->cronjobs[$key][
'frequency'] :
'';
1446 $unitfrequency = isset($this->cronjobs[$key][
'unitfrequency']) ? $this->cronjobs[$key][
'unitfrequency'] :
'';
1447 $priority = isset($this->cronjobs[$key][
'priority']) ? $this->cronjobs[$key][
'priority'] :
'';
1448 $datestart = isset($this->cronjobs[$key][
'datestart']) ? $this->cronjobs[$key][
'datestart'] :
'';
1449 $dateend = isset($this->cronjobs[$key][
'dateend']) ? $this->cronjobs[$key][
'dateend'] :
'';
1450 $status = isset($this->cronjobs[$key][
'status']) ? $this->cronjobs[$key][
'status'] :
'';
1451 $test = isset($this->cronjobs[$key][
'test']) ? $this->cronjobs[$key][
'test'] :
'';
1454 $sql =
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"cronjob";
1456 $sql .=
" WHERE label = '".$this->db->escape($label).
"'";
1472 $sql .=
" AND entity = ".((int) $entity);
1476 $result = $this->
db->query($sql);
1478 $obj = $this->
db->fetch_object($result);
1479 if ($obj->nb == 0) {
1483 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"cronjob (module_name, datec, datestart, dateend, label, jobtype, classesname, objectname, methodename, command, params, note,";
1484 if (is_int($frequency)) {
1485 $sql .=
' frequency,';
1487 if (is_int($unitfrequency)) {
1488 $sql .=
' unitfrequency,';
1490 if (is_int($priority)) {
1491 $sql .=
' priority,';
1493 if (is_int($status)) {
1496 $sql .=
" entity, test)";
1497 $sql .=
" VALUES (";
1498 $sql .=
"'".$this->db->escape(empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class).
"', ";
1499 $sql .=
"'".$this->db->idate($now).
"', ";
1500 $sql .= ($datestart ?
"'".$this->db->idate($datestart).
"'" :
"'".$this->db->idate($now).
"'").
", ";
1501 $sql .= ($dateend ?
"'".$this->db->idate($dateend).
"'" :
"NULL").
", ";
1502 $sql .=
"'".$this->db->escape($label).
"', ";
1503 $sql .=
"'".$this->db->escape($jobtype).
"', ";
1504 $sql .= ($class ?
"'".$this->db->escape($class).
"'" :
"null").
",";
1505 $sql .= ($objectname ?
"'".$this->db->escape($objectname).
"'" :
"null").
",";
1506 $sql .= ($method ?
"'".$this->db->escape($method).
"'" :
"null").
",";
1507 $sql .= ($command ?
"'".$this->db->escape($command).
"'" :
"null").
",";
1508 $sql .= ($parameters ?
"'".$this->db->escape($parameters).
"'" :
"null").
",";
1509 $sql .= ($comment ?
"'".$this->db->escape($comment).
"'" :
"null").
",";
1510 if (is_int($frequency)) {
1511 $sql .=
"'".$this->db->escape($frequency).
"', ";
1513 if (is_int($unitfrequency)) {
1514 $sql .=
"'".$this->db->escape($unitfrequency).
"', ";
1516 if (is_int($priority)) {
1517 $sql .=
"'".$this->db->escape($priority).
"', ";
1519 if (is_int($status)) {
1520 $sql .= ((int) $status).
", ";
1522 $sql .= $entity.
",";
1523 $sql .=
"'".$this->db->escape($test).
"'";
1533 $this->
db->commit();
1535 $this->error = $this->
db->lasterror();
1536 $this->
db->rollback();
1541 $this->error = $this->
db->lasterror();
1564 if (is_array($this->cronjobs)) {
1565 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"cronjob";
1566 $sql .=
" WHERE module_name = '".$this->db->escape(empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class).
"'";
1567 $sql .=
" AND entity = ".$conf->entity;
1568 $sql .=
" AND test = '1'";
1571 dol_syslog(get_class($this).
"::delete_cronjobs", LOG_DEBUG);
1574 $this->error = $this->
db->lasterror();
1595 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
1596 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" like '".$this->
db->escape($this->const_name).
"_TABS_%'";
1597 $sql .=
" AND entity = ".$conf->entity;
1599 dol_syslog(get_class($this).
"::delete_tabs", LOG_DEBUG);
1600 if (!$this->
db->query($sql)) {
1601 $this->error = $this->
db->lasterror();
1621 if (!empty($this->tabs)) {
1622 dol_syslog(get_class($this).
"::insert_tabs", LOG_DEBUG);
1625 foreach ($this->tabs as $key => $value) {
1626 if (is_array($value) && count($value) == 0) {
1630 $entity = $conf->entity;
1633 if (is_array($value)) {
1634 $newvalue = $value[
'data'];
1635 if (isset($value[
'entity'])) {
1636 $entity = $value[
'entity'];
1641 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (";
1646 $sql .=
", visible";
1649 $sql .=
" VALUES (";
1650 $sql .= $this->
db->encrypt($this->const_name.
"_TABS_".$i);
1651 $sql .=
", 'chaine'";
1652 $sql .=
", ".$this->db->encrypt($newvalue);
1655 $sql .=
", ".((int) $entity);
1661 if ($this->
db->lasterrno() !=
'DB_ERROR_RECORD_ALREADY_EXISTS') {
1662 $this->error = $this->
db->lasterror();
1663 $this->errors[] = $this->
db->lasterror();
1688 if (empty($this->
const)) {
1692 dol_syslog(get_class($this).
"::insert_const", LOG_DEBUG);
1694 foreach ($this->
const as $key => $value) {
1695 $name = $this->
const[$key][0];
1696 $type = $this->
const[$key][1];
1697 $val = $this->
const[$key][2];
1698 $note = isset($this->
const[$key][3]) ? $this->
const[$key][3] :
'';
1699 $visible = isset($this->
const[$key][4]) ? $this->
const[$key][4] : 0;
1700 $entity = (!empty($this->
const[$key][5]) && $this->
const[$key][5] !=
'current') ? 0 : $conf->entity;
1703 if (empty($visible)) {
1706 if (empty($val) && $val !=
'0') {
1710 $sql =
"SELECT count(*)";
1711 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const";
1712 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($name).
"'";
1713 $sql .=
" AND entity = ".((int) $entity);
1715 $result = $this->
db->query($sql);
1717 $row = $this->
db->fetch_row($result);
1720 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name,type,value,note,visible,entity)";
1721 $sql .=
" VALUES (";
1722 $sql .= $this->
db->encrypt($name);
1723 $sql .=
",'".$this->db->escape($type).
"'";
1724 $sql .=
",".(($val !=
'') ? $this->
db->encrypt($val) :
"''");
1725 $sql .=
",".($note ?
"'".$this->db->escape($note).
"'" :
"null");
1726 $sql .=
",'".$this->db->escape($visible).
"'";
1727 $sql .=
",".$entity;
1730 if (!$this->
db->query($sql)) {
1734 dol_syslog(get_class($this).
"::insert_const constant '".$name.
"' already exists", LOG_WARNING);
1757 if (empty($this->
const)) {
1761 foreach ($this->
const as $key => $value) {
1762 $name = $this->
const[$key][0];
1763 $deleteonunactive = (!empty($this->
const[$key][6])) ? 1 : 0;
1765 if ($deleteonunactive) {
1766 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
1767 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($name).
"'";
1768 $sql .=
" AND entity in (0, ".$conf->entity.
")";
1769 dol_syslog(get_class($this).
"::delete_const", LOG_DEBUG);
1770 if (!$this->
db->query($sql)) {
1771 $this->error = $this->
db->lasterror();
1792 global $conf, $user;
1795 $entity = (!empty($force_entity) ? $force_entity : $conf->entity);
1797 dol_syslog(get_class($this).
"::insert_permissions", LOG_DEBUG);
1800 $sql_del =
"SELECT ".$this->db->decrypt(
'value').
" as value";
1801 $sql_del .=
" FROM ".MAIN_DB_PREFIX.
"const";
1802 $sql_del .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
1803 $sql_del .=
" AND entity IN (0,".$entity.
")";
1805 $resql = $this->
db->query($sql_del);
1808 $obj = $this->
db->fetch_object(
$resql);
1810 if ($obj !==
null && !empty($obj->value) && !empty($this->rights)) {
1811 include_once DOL_DOCUMENT_ROOT.
'/user/class/user.class.php';
1814 foreach ($this->rights as $key => $value) {
1815 $r_id = $this->rights[$key][0];
1816 $r_desc = $this->rights[$key][1];
1817 $r_type = isset($this->rights[$key][2]) ? $this->rights[$key][2] :
'';
1818 $r_def = empty($this->rights[$key][3]) ? 0 : $this->rights[$key][3];
1819 $r_perms = $this->rights[$key][4];
1820 $r_subperms = isset($this->rights[$key][5]) ? $this->rights[$key][5] :
'';
1821 $r_modul = empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class;
1823 if (empty($r_type)) {
1828 $sql =
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"rights_def";
1829 $sql .=
" WHERE id = ".((int) $r_id).
" AND entity = ".((int) $entity);
1831 $resqlselect = $this->
db->query($sql);
1833 $objcount = $this->
db->fetch_object($resqlselect);
1834 if ($objcount && $objcount->nb == 0) {
1837 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"rights_def";
1838 $sql .=
" (id, entity, libelle, module, type, bydefault, perms, subperms)";
1840 $sql .=
"(".$r_id.
",".$entity.
",'".$this->
db->escape($r_desc).
"','".$this->
db->escape($r_modul).
"','".$this->
db->escape($r_type).
"',".$r_def.
",'".$this->
db->escape($r_perms).
"','".$this->
db->escape($r_subperms).
"')";
1842 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"rights_def";
1843 $sql .=
" (id, entity, libelle, module, type, bydefault, perms)";
1845 $sql .=
"(".$r_id.
",".$entity.
",'".$this->
db->escape($r_desc).
"','".$this->
db->escape($r_modul).
"','".$this->
db->escape($r_type).
"',".$r_def.
",'".$this->
db->escape($r_perms).
"')";
1848 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"rights_def ";
1849 $sql .=
" (id, entity, libelle, module, type, bydefault)";
1851 $sql .=
"(".$r_id.
",".$entity.
",'".$this->
db->escape($r_desc).
"','".$this->
db->escape($r_modul).
"','".$this->
db->escape($r_type).
"',".$r_def.
")";
1854 $resqlinsert = $this->
db->query($sql, 1);
1856 if (!$resqlinsert) {
1857 if ($this->
db->errno() !=
"DB_ERROR_RECORD_ALREADY_EXISTS") {
1858 $this->error = $this->
db->lasterror();
1862 dol_syslog(get_class($this).
"::insert_permissions record already exists", LOG_INFO);
1866 $this->
db->free($resqlinsert);
1869 $this->
db->free($resqlselect);
1873 if ($reinitadminperms) {
1874 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"user WHERE admin = 1";
1875 dol_syslog(get_class($this).
"::insert_permissions Search all admin users", LOG_DEBUG);
1877 $resqlseladmin = $this->
db->query($sql, 1);
1879 if ($resqlseladmin) {
1880 $num = $this->
db->num_rows($resqlseladmin);
1883 $obj2 = $this->
db->fetch_object($resqlseladmin);
1884 dol_syslog(get_class($this).
"::insert_permissions Add permission id '.$r_id.' to user id=".$obj2->rowid);
1886 $tmpuser =
new User($this->
db);
1887 $result = $tmpuser->fetch($obj2->rowid);
1889 $tmpuser->addrights($r_id,
'',
'', 0, 1);
1891 dol_syslog(get_class($this).
"::insert_permissions Failed to add the permission to user because fetch return an error", LOG_ERR);
1901 if ($reinitadminperms && !empty($user->admin)) {
1903 $user->clearrights();
1909 $this->error = $this->
db->lasterror();
1930 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def";
1931 $sql .=
" WHERE module = '".$this->db->escape(empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class).
"'";
1932 $sql .=
" AND entity = ".$conf->entity;
1933 dol_syslog(get_class($this).
"::delete_permissions", LOG_DEBUG);
1934 if (!$this->
db->query($sql)) {
1935 $this->error = $this->
db->lasterror();
1954 if (!is_array($this->menu) || empty($this->menu)) {
1958 include_once DOL_DOCUMENT_ROOT.
'/core/class/menubase.class.php';
1960 dol_syslog(get_class($this).
"::insert_menus", LOG_DEBUG);
1966 foreach ($this->menu as $key => $value) {
1968 $menu->menu_handler =
'all';
1971 $menu->module = empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class;
1973 if (!$this->menu[$key][
'fk_menu']) {
1977 $fk_parent = $this->menu[$key][
'fk_menu'];
1978 if (preg_match(
'/^r=/', $fk_parent)) {
1979 $fk_parent = str_replace(
'r=',
'', $fk_parent);
1980 if (isset($this->menu[$fk_parent][
'rowid'])) {
1981 $menu->fk_menu = $this->menu[$fk_parent][
'rowid'];
1984 } elseif (preg_match(
'/^fk_mainmenu=([a-zA-Z0-9_]+),fk_leftmenu=([a-zA-Z0-9_]+)$/', $fk_parent, $reg)) {
1985 $menu->fk_menu = -1;
1986 $menu->fk_mainmenu = $reg[1];
1987 $menu->fk_leftmenu = $reg[2];
1989 } elseif (preg_match(
'/^fk_mainmenu=([a-zA-Z0-9_]+)$/', $fk_parent, $reg)) {
1990 $menu->fk_menu = -1;
1991 $menu->fk_mainmenu = $reg[1];
1992 $menu->fk_leftmenu =
'';
1995 if (!$foundparent) {
1996 $this->error =
"ErrorBadDefinitionOfMenuArrayInModuleDescriptor";
1997 dol_syslog(get_class($this).
"::insert_menus ".$this->error.
" ".$this->menu[$key][
'fk_menu'], LOG_ERR);
2001 $menu->type = $this->menu[$key][
'type'];
2002 $menu->mainmenu = isset($this->menu[$key][
'mainmenu']) ? $this->menu[$key][
'mainmenu'] : (isset($menu->fk_mainmenu) ? $menu->fk_mainmenu :
'');
2003 $menu->leftmenu = isset($this->menu[$key][
'leftmenu']) ? $this->menu[$key][
'leftmenu'] :
'';
2004 $menu->title = $this->menu[$key][
'titre'];
2005 $menu->prefix = isset($this->menu[$key][
'prefix']) ? $this->menu[$key][
'prefix'] :
'';
2006 $menu->url = $this->menu[$key][
'url'];
2007 $menu->langs = isset($this->menu[$key][
'langs']) ? $this->menu[$key][
'langs'] :
'';
2008 $menu->position = $this->menu[$key][
'position'];
2009 $menu->perms = $this->menu[$key][
'perms'];
2010 $menu->target = isset($this->menu[$key][
'target']) ? $this->menu[$key][
'target'] :
'';
2011 $menu->user = $this->menu[$key][
'user'];
2012 $menu->enabled = isset($this->menu[$key][
'enabled']) ? $this->menu[$key][
'enabled'] : 0;
2013 $menu->position = $this->menu[$key][
'position'];
2016 $result = $menu->create($user);
2018 $this->menu[$key][
'rowid'] = $result;
2020 $this->error = $menu->error;
2021 dol_syslog(get_class($this).
'::insert_menus result='.$result.
" ".$this->error, LOG_ERR);
2029 $this->
db->commit();
2031 dol_syslog(get_class($this).
"::insert_menus ".$this->error, LOG_ERR);
2032 $this->
db->rollback();
2053 $module = empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class;
2055 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"menu";
2056 $sql .=
" WHERE module = '".$this->db->escape($module).
"'";
2057 $sql .=
" AND entity = ".$conf->entity;
2059 dol_syslog(get_class($this).
"::delete_menus", LOG_DEBUG);
2062 $this->error = $this->
db->lasterror();
2078 global $langs, $conf;
2082 if (isset($this->dirs) && is_array($this->dirs)) {
2083 foreach ($this->dirs as $key => $value) {
2086 if (!is_array($value)) {
2089 $constname = $this->const_name.
"_DIR_";
2090 $dir = $this->dirs[$key][1];
2091 $addtodatabase = empty($this->dirs[$key][2]) ?
'' : $this->dirs[$key][2];
2092 $subname = empty($this->dirs[$key][3]) ?
'' : strtoupper($this->dirs[$key][3]);
2093 $forcename = empty($this->dirs[$key][4]) ?
'' : strtoupper($this->dirs[$key][4]);
2095 if (!empty($forcename)) {
2096 $constname =
'MAIN_MODULE_'.$forcename.
"_DIR_";
2098 if (!empty($subname)) {
2099 $constname = $constname.$subname.
"_";
2102 $name = $constname.strtoupper($this->dirs[$key][0]);
2106 if (empty($conf->global->MAIN_MODULE_MULTICOMPANY) || $conf->entity == 1) {
2107 $fulldir = DOL_DATA_ROOT.$dir;
2109 $fulldir = DOL_DATA_ROOT.
"/".$conf->entity.$dir;
2112 if (!empty($fulldir) && !file_exists($fulldir)) {
2113 if (
dol_mkdir($fulldir, DOL_DATA_ROOT) < 0) {
2114 $this->error = $langs->trans(
"ErrorCanNotCreateDir", $fulldir);
2115 dol_syslog(get_class($this).
"::_init ".$this->error, LOG_ERR);
2121 if (!empty($addtodatabase)) {
2150 $sql =
"SELECT count(*)";
2151 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const";
2152 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($name).
"'";
2153 $sql .=
" AND entity = ".$conf->entity;
2155 dol_syslog(get_class($this).
"::insert_dirs", LOG_DEBUG);
2156 $result = $this->
db->query($sql);
2158 $row = $this->
db->fetch_row($result);
2161 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name, type, value, note, visible, entity)";
2162 $sql .=
" VALUES (".$this->db->encrypt($name).
", 'chaine', ".$this->
db->encrypt($dir).
", '".$this->
db->escape(
"Directory for module ".$this->
name).
"', '0', ".((int) $conf->entity).
")";
2164 dol_syslog(get_class($this).
"::insert_dirs", LOG_DEBUG);
2165 $this->
db->query($sql);
2168 $this->error = $this->
db->lasterror();
2189 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
2190 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" LIKE '".$this->
db->escape($this->const_name).
"_DIR_%'";
2191 $sql .=
" AND entity = ".$conf->entity;
2193 dol_syslog(get_class($this).
"::delete_dirs", LOG_DEBUG);
2194 if (!$this->
db->query($sql)) {
2195 $this->error = $this->
db->lasterror();
2215 if (is_array($this->module_parts) && !empty($this->module_parts)) {
2216 foreach ($this->module_parts as $key => $value) {
2217 if (is_array($value) && count($value) == 0) {
2221 $entity = $conf->entity;
2225 if (is_array($value)) {
2228 if (isset($value[
'data']) && is_array($value[
'data'])) {
2229 $newvalue = json_encode($value[
'data']);
2230 if (isset($value[
'entity'])) {
2231 $entity = $value[
'entity'];
2233 } elseif (isset($value[
'data']) && !is_array($value[
'data'])) {
2234 $newvalue = $value[
'data'];
2235 if (isset($value[
'entity'])) {
2236 $entity = $value[
'entity'];
2239 $newvalue = json_encode($value);
2243 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (";
2248 $sql .=
", visible";
2251 $sql .=
" VALUES (";
2252 $sql .=
" ".$this->db->encrypt($this->const_name.
"_".strtoupper($key));
2253 $sql .=
", 'chaine'";
2254 $sql .=
", ".$this->db->encrypt($newvalue);
2257 $sql .=
", ".((int) $entity);
2260 dol_syslog(get_class($this).
"::insert_module_parts for key=".$this->const_name.
"_".strtoupper($key), LOG_DEBUG);
2262 $resql = $this->
db->query($sql, 1);
2264 if ($this->
db->lasterrno() !=
'DB_ERROR_RECORD_ALREADY_EXISTS') {
2266 $this->error = $this->
db->lasterror();
2268 dol_syslog(get_class($this).
"::insert_module_parts for ".$this->const_name.
"_".strtoupper($key).
" Record already exists.", LOG_WARNING);
2288 $entity = $conf->entity;
2290 if (is_array($this->module_parts) && !empty($this->module_parts)) {
2291 dol_syslog(get_class($this).
"::delete_module_parts", LOG_DEBUG);
2293 foreach ($this->module_parts as $key => $value) {
2295 if (is_array($value) && isset($value[
'entity'])) {
2296 $entity = $value[
'entity'];
2299 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
2300 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" LIKE '".$this->
db->escape($this->const_name).
"_".strtoupper($key).
"'";
2301 $sql .=
" AND entity = ".((int) $entity);
2303 if (!$this->
db->query($sql)) {
2304 $this->error = $this->
db->lasterror();
2321 public function init($options =
'')
2323 return $this->
_init(array(), $options);
2334 public function remove($options =
'')
2336 return $this->
_remove(array(), $options);
2349 global $conf, $langs;
2354 $imginfo =
"info_black";
2357 $const_name =
'MAIN_MODULE_'.strtoupper(preg_replace(
'/^mod/i',
'', get_class($this)));
2361 if (preg_match(
'/development/i', $version)) {
2362 $versiontrans .=
'warning';
2364 if (preg_match(
'/experimental/i', $version)) {
2365 $versiontrans .=
'warning';
2367 if (preg_match(
'/deprecated/i', $version)) {
2368 $versiontrans .=
'warning';
2372 <div class="box-flex-item info-box-module'
2373 .(empty($conf->global->$const_name) ?
' --disabled' :
'')
2375 .($this->needUpdate ?
' --need-update' :
'')
2377 <div class="info-box info-box-sm info-box-module">
2378 <div class="info-box-icon'.(empty($conf->global->$const_name) ?
'' :
' info-box-icon-module-enabled'.($versiontrans ?
' info-box-icon-module-warning' :
'')).
'">';
2383 if (!empty($this->picto)) {
2384 if (preg_match(
'/^\//i', $this->picto)) {
2385 print
img_picto($alttext, $this->picto,
'class="inline-block valignmiddle"', 1);
2387 print
img_object($alttext, $this->picto,
'class="inline-block valignmiddle"');
2390 print
img_object($alttext,
'generic',
'class="inline-block valignmiddle"');
2393 if ($this->
isCoreOrExternalModule() ==
'external' || preg_match(
'/development|experimental|deprecated/i', $version)) {
2394 $versionTitle = $langs->trans(
"Version").
' '.$this->
getVersion(1);
2395 if ($this->needUpdate) {
2396 $versionTitle.=
'<br>'.$langs->trans(
'ModuleUpdateAvailable').
' : '.
$this->lastVersion;
2399 print
'<span class="info-box-icon-version'.($versiontrans ?
' '.$versiontrans :
'').
' classfortooltip" title="'.
dol_escape_js($versionTitle).
'" >';
2405 <div class="info-box-content info-box-text-module'.(empty($conf->global->$const_name) ?
'' :
' info-box-module-enabled'.($versiontrans ?
' info-box-content-warning' :
'')).
'">
2406 <span class="info-box-title">'.$this->
getName().
'</span>
2409 print
'<div class="valignmiddle inline-block info-box-more">';
2411 print
'<a class="valignmiddle inline-block" href="javascript:document_preview(\''.DOL_URL_ROOT.
'/admin/modulehelp.php?id='.$this->numero.
'\',\
'text/html\',\''.dol_escape_js($langs->trans(
"Module")).
'\')
">'.img_picto(($this->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule
").' - ' : '').$langs->trans("ClickToShowDescription
"), $imginfo).'</a>';
2414 print '<div class="valignmiddle
inline-block info-box-actions
">';
2415 print '<div class="valignmiddle
inline-block info-box-setup
">';
2416 print $codetoconfig;
2418 print '<div class="valignmiddle
inline-block marginleftonly marginrightonly
">';
2419 print $codeenabledisable;
2424 </div><!-- /.info-box-content -->
2425 </div><!-- /.info-box -->
2436 public function checkForUpdate()
2438 require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
2439 if (!empty($this->url_last_version)) {
2440 $lastVersion = getURLContent($this->url_last_version, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
2441 if (isset($lastVersion['content']) && strlen($lastVersion['content']) < 30) {
2442 // Security warning : be careful with remote data content, the module editor could be hacked (or evil) so limit to a-z A-Z 0-9 _ . -
2443 $this->lastVersion = preg_replace("/[^a-zA-Z0-9_\.\-]+/
", "", $lastVersion['content']);
2444 if (version_compare($this->lastVersion, $this->version) > 0) {
2445 $this->needUpdate = true;
2448 $this->needUpdate = false;