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 =
"-";
225 public $descriptionlong;
230 public $dictionaries;
247 public $export_label;
251 public $export_permission;
252 public $export_fields_array;
253 public $export_TypeFields_array;
254 public $export_entities_array;
255 public $export_help_array;
256 public $export_special_array;
257 public $export_dependencies_array;
258 public $export_sql_start;
259 public $export_sql_end;
260 public $export_sql_order;
273 public $import_label;
277 public $import_entities_array;
278 public $import_tables_array;
279 public $import_fields_array;
280 public $import_fieldshidden_array;
281 public $import_convertvalue_array;
282 public $import_regex_array;
283 public $import_examplevalues_array;
284 public $import_updatekeys_array;
295 public $always_enabled;
305 public $core_enabled;
321 public $config_page_url;
340 public $conflictwith;
352 public $warnings_activation;
359 public $warnings_activation_ext;
374 public $need_dolibarr_version;
376 public $enabled_bydefault;
381 public $hidden =
false;
386 public $url_last_version;
415 protected function _init($array_sql, $options =
'')
439 if (!$err && !preg_match(
'/newboxdefonly/', $options)) {
444 if (!$err && !preg_match(
'/noboxes/', $options)) {
469 $num = count($array_sql);
470 for ($i = 0; $i < $num; $i++) {
472 $val = $array_sql[$i];
475 if (is_array($val)) {
477 $ignoreerror = $val[
'ignoreerror'];
480 $sql = str_replace(
'__ENTITY__', $conf->entity,
$sql);
482 dol_syslog(get_class($this).
"::_init ignoreerror=".$ignoreerror, LOG_DEBUG);
483 $result = $this->
db->query(
$sql, $ignoreerror);
486 $this->error = $this->
db->lasterror();
489 dol_syslog(get_class($this).
"::_init Warning ".$this->
db->lasterror(), LOG_WARNING);
500 $this->
db->rollback();
514 protected function _remove($array_sql, $options =
'')
542 if (!$err && !preg_match(
'/(newboxdefonly|noboxes)/', $options)) {
567 $num = count($array_sql);
568 for ($i = 0; $i < $num; $i++) {
570 dol_syslog(get_class($this).
"::_remove", LOG_DEBUG);
571 $result = $this->
db->query($array_sql[$i]);
573 $this->error = $this->
db->error();
584 $this->
db->rollback();
599 $langs->load(
"admin");
601 if ($langs->transnoentitiesnoconv(
"Module".$this->numero.
"Name") != (
"Module".$this->numero.
"Name")) {
603 return $langs->transnoentitiesnoconv(
"Module".$this->numero.
"Name");
606 if (is_array($this->langfiles)) {
607 foreach ($this->langfiles as $val) {
614 if ($langs->trans(
"Module".$this->name.
"Name") != (
"Module".$this->name.
"Name")) {
616 return $langs->transnoentitiesnoconv(
"Module".$this->
name.
"Name");
620 return $langs->transnoentitiesnoconv($this->
name);
633 $langs->load(
"admin");
635 if ($langs->transnoentitiesnoconv(
"Module".$this->numero.
"Desc") != (
"Module".$this->numero.
"Desc")) {
637 return $langs->transnoentitiesnoconv(
"Module".$this->numero.
"Desc");
640 if (is_array($this->langfiles)) {
641 foreach ($this->langfiles as $val) {
648 if ($langs->transnoentitiesnoconv(
"Module".$this->name.
"Desc") != (
"Module".$this->name.
"Desc")) {
650 return $langs->trans(
"Module".$this->
name.
"Desc");
667 $langs->load(
"admin");
669 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
670 include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
676 $content = file_get_contents($pathoffile);
678 if ((
float) DOL_VERSION >= 6.0) {
679 @include_once DOL_DOCUMENT_ROOT.
'/core/lib/parsemd.lib.php';
691 $content = nl2br($content);
695 if (!empty($this->descriptionlong)) {
696 if (is_array($this->langfiles)) {
697 foreach ($this->langfiles as $val) {
704 $content = $langs->transnoentitiesnoconv($this->descriptionlong);
724 $pathoffile =
dol_buildpath(strtolower($this->
name).
'/README-'.$langs->defaultlang.
'.md', 0);
729 $tmp = explode(
'_', $langs->defaultlang);
730 $pathoffile =
dol_buildpath(strtolower($this->
name).
'/README-'.$tmp[0].
'.md', 0);
742 return ($filefound ? $pathoffile :
'');
754 $langs->load(
"admin");
756 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
757 include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
763 $pathoffile =
dol_buildpath(strtolower($this->
name).
'/ChangeLog-'.$langs->defaultlang.
'.md', 0);
775 $content = file_get_contents($pathoffile);
777 if ((
float) DOL_VERSION >= 6.0) {
778 @include_once DOL_DOCUMENT_ROOT.
'/core/lib/parsemd.lib.php';
781 $content = nl2br($content);
795 return $this->editor_name;
805 return $this->editor_url;
819 $langs->load(
"admin");
823 $newversion = preg_replace(
'/_deprecated/',
'', $this->version);
824 if ($newversion ==
'experimental') {
825 $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionExperimental") : $newversion);
826 } elseif ($newversion ==
'development') {
827 $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionDevelopment") : $newversion);
828 } elseif ($newversion ==
'dolibarr') {
830 } elseif ($newversion) {
833 $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionUnknown") :
'unknown');
836 if (preg_match(
'/_deprecated/', $this->version)) {
837 $ret .= ($translated ?
' ('.$langs->transnoentitiesnoconv(
"Deprecated").
')' : $this->version);
849 if (in_array($this->version, array(
'dolibarr',
'experimental',
'development'))) {
850 return $this->module_position;
852 if ($this->module_position >= 100000) {
853 return $this->module_position;
855 return $this->module_position + 100000;
869 if ($this->version ==
'dolibarr' || $this->version ==
'dolibarr_deprecated') {
872 if (!empty($this->version) && !in_array($this->version, array(
'experimental',
'development'))) {
875 if (!empty($this->editor_name) || !empty($this->editor_url)) {
878 if ($this->numero >= 100000) {
892 return $this->langfiles;
906 $langstring =
"ExportDataset_".$this->export_code[$r];
907 if ($langs->trans($langstring) == $langstring) {
909 return $langs->trans($this->export_label[$r]);
912 return $langs->trans($langstring);
928 $langstring =
"ImportDataset_".$this->import_code[$r];
930 if ($langs->trans($langstring) == $langstring) {
932 return $langs->transnoentitiesnoconv($this->import_label[$r]);
935 return $langs->transnoentitiesnoconv($langstring);
951 $sql =
"SELECT tms FROM ".MAIN_DB_PREFIX.
"const";
952 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
953 $sql .=
" AND entity IN (0, ".$conf->entity.
")";
955 dol_syslog(get_class($this).
"::getLastActiveDate", LOG_DEBUG);
956 $resql = $this->
db->query(
$sql);
960 $obj = $this->
db->fetch_object($resql);
962 return $this->
db->jdate($obj->tms);
981 $sql =
"SELECT tms, note FROM ".MAIN_DB_PREFIX.
"const";
982 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
983 $sql .=
" AND entity IN (0, ".$conf->entity.
")";
985 dol_syslog(get_class($this).
"::getLastActiveDate", LOG_DEBUG);
986 $resql = $this->
db->query(
$sql);
990 $obj = $this->
db->fetch_object($resql);
994 $tmp = json_decode($obj->note,
true);
997 'authorid' => empty($tmp[
'authorid']) ?
'' : $tmp[
'authorid'],
998 'ip' => empty($tmp[
'ip']) ?
'' : $tmp[
'ip'],
999 'lastactivationdate' => $this->
db->jdate($obj->tms),
1000 'lastactivationversion' => (!empty($tmp[
'lastactivationversion']) ? $tmp[
'lastactivationversion'] :
'unknown'),
1018 global $conf, $user;
1023 $entity = ((!empty($this->always_enabled) || !empty($this->core_enabled)) ? 0 : $conf->entity);
1025 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
1026 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
1027 $sql .=
" AND entity IN (0, ".$entity.
")";
1029 dol_syslog(get_class($this).
"::_active delete activation constant", LOG_DEBUG);
1030 $resql = $this->
db->query(
$sql);
1035 $note = json_encode(
1037 'authorid' => (is_object($user) ? $user->id : 0),
1038 'ip' => (empty($_SERVER[
'REMOTE_ADDR']) ?
'' : $_SERVER[
'REMOTE_ADDR']),
1039 'lastactivationversion' => $this->version,
1043 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name, value, visible, entity, note) VALUES";
1044 $sql .=
" (".$this->db->encrypt($this->const_name);
1045 $sql .=
", ".$this->db->encrypt(
'1');
1046 $sql .=
", 0, ".((int) $entity);
1047 $sql .=
", '".$this->db->escape($note).
"')";
1049 dol_syslog(get_class($this).
"::_active insert activation constant", LOG_DEBUG);
1050 $resql = $this->
db->query(
$sql);
1073 $entity = ((!empty($this->always_enabled) || !empty($this->core_enabled)) ? 0 : $conf->entity);
1075 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
1076 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
1077 $sql .=
" AND entity IN (0, ".$entity.
")";
1079 dol_syslog(get_class($this).
"::_unactive", LOG_DEBUG);
1110 if (empty($reldir)) {
1114 include_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
1117 foreach ($conf->file->dol_document_root as $dirroot) {
1119 $dirsql = $dirroot.$reldir;
1123 $listofsubdir = array(
'',
'tables/',
'data/');
1124 if ($this->
db->type ==
'pgsql') {
1125 $listofsubdir[] =
'../pgsql/functions/';
1128 foreach ($listofsubdir as $subdir) {
1129 $dir = $dirsql.$subdir;
1131 $handle = @opendir($dir);
1132 if (is_resource($handle)) {
1137 while (($file = readdir($handle)) !==
false) {
1141 foreach ($files as $file) {
1142 if ($onlywithsuffix) {
1143 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1150 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) ==
'llx_') {
1151 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1162 while (($file = readdir($handle)) !==
false) {
1166 foreach ($files as $file) {
1167 if ($onlywithsuffix) {
1168 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1175 if (preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) ==
'llx_') {
1176 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1187 while (($file = readdir($handle)) !==
false) {
1191 foreach ($files as $file) {
1192 if ($onlywithsuffix) {
1193 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1200 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 9) ==
'functions') {
1201 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1212 while (($file = readdir($handle)) !==
false) {
1216 foreach ($files as $file) {
1217 if ($onlywithsuffix) {
1218 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1225 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) ==
'data') {
1226 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1237 while (($file = readdir($handle)) !==
false) {
1241 foreach ($files as $file) {
1242 if ($onlywithsuffix) {
1243 if (!preg_match(
'/\-'.preg_quote($onlywithsuffix,
'/').
'\./i', $file)) {
1250 if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 6) ==
'update') {
1251 $result =
run_sql($dir.$file, empty($conf->global->MAIN_DISPLAY_SQL_INSTALL_LOG) ? 1 : 0,
'', 1);
1269 dol_syslog(
"A module ask to load sql files into ".$reldir.
" but this directory was not found.", LOG_WARNING);
1286 include_once DOL_DOCUMENT_ROOT.
'/core/class/infobox.class.php';
1292 if (is_array($this->boxes)) {
1293 dol_syslog(get_class($this).
"::insert_boxes", LOG_DEBUG);
1297 foreach ($this->boxes as $key => $value) {
1298 $file = isset($this->boxes[$key][
'file']) ? $this->boxes[$key][
'file'] :
'';
1299 $note = isset($this->boxes[$key][
'note']) ? $this->boxes[$key][
'note'] :
'';
1300 $enabledbydefaulton = isset($this->boxes[$key][
'enabledbydefaulton']) ? $this->boxes[$key][
'enabledbydefaulton'] :
'Home';
1303 $file = isset($this->boxes[$key][1]) ? $this->boxes[$key][1] :
'';
1306 $note = isset($this->boxes[$key][2]) ? $this->boxes[$key][2] :
'';
1310 $sql =
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"boxes_def";
1311 $sql .=
" WHERE file = '".$this->db->escape($file).
"'";
1312 $sql .=
" AND entity = ".$conf->entity;
1314 $sql .=
" AND note ='".$this->db->escape($note).
"'";
1317 $result = $this->
db->query(
$sql);
1319 $obj = $this->
db->fetch_object($result);
1320 if ($obj->nb == 0) {
1324 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"boxes_def (file, entity, note)";
1325 $sql .=
" VALUES ('".$this->db->escape($file).
"', ";
1326 $sql .= $conf->entity.
", ";
1327 $sql .= $note ?
"'".$this->db->escape($note).
"'" :
"null";
1330 dol_syslog(get_class($this).
"::insert_boxes", LOG_DEBUG);
1331 $resql = $this->
db->query(
$sql);
1336 if (!$err && !preg_match(
'/newboxdefonly/', $option)) {
1337 $lastid = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"boxes_def",
"rowid");
1339 foreach ($pos_name as $key2 => $val2) {
1341 if ($enabledbydefaulton && $val2 != $enabledbydefaulton) {
1345 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"boxes (box_id, position, box_order, fk_user, entity)";
1346 $sql .=
" VALUES (".((int) $lastid).
", ".((int) $key2).
", '0', 0, ".((int) $conf->entity).
")";
1348 dol_syslog(get_class($this).
"::insert_boxes onto page ".$key2.
"=".$val2, LOG_DEBUG);
1349 $resql = $this->
db->query(
$sql);
1357 $this->
db->commit();
1359 $this->error = $this->
db->lasterror();
1360 $this->
db->rollback();
1365 $this->error = $this->
db->lasterror();
1388 if (is_array($this->boxes)) {
1389 foreach ($this->boxes as $key => $value) {
1391 if (empty($this->boxes[$key][
'file'])) {
1392 $file = isset($this->boxes[$key][1]) ? $this->boxes[$key][1] :
'';
1394 $file = $this->boxes[$key][
'file'];
1402 if ($file ==
'box_graph_product_distribution.php') {
1404 dol_syslog(
"We discard deleting module ".$file.
" because another module still active requires it.");
1409 if ($this->
db->type ==
'sqlite3') {
1412 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes ";
1413 $sql .=
"WHERE ".MAIN_DB_PREFIX.
"boxes.box_id IN (";
1414 $sql .=
"SELECT ".MAIN_DB_PREFIX.
"boxes_def.rowid ";
1415 $sql .=
"FROM ".MAIN_DB_PREFIX.
"boxes_def ";
1416 $sql .=
"WHERE ".MAIN_DB_PREFIX.
"boxes_def.file = '".$this->
db->escape($file).
"') ";
1417 $sql .=
"AND ".MAIN_DB_PREFIX.
"boxes.entity = ".$conf->entity;
1419 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes";
1420 $sql .=
" USING ".MAIN_DB_PREFIX.
"boxes, ".MAIN_DB_PREFIX.
"boxes_def";
1421 $sql .=
" WHERE ".MAIN_DB_PREFIX.
"boxes.box_id = ".MAIN_DB_PREFIX.
"boxes_def.rowid";
1422 $sql .=
" AND ".MAIN_DB_PREFIX.
"boxes_def.file = '".$this->
db->escape($file).
"'";
1423 $sql .=
" AND ".MAIN_DB_PREFIX.
"boxes.entity = ".$conf->entity;
1426 dol_syslog(get_class($this).
"::delete_boxes", LOG_DEBUG);
1427 $resql = $this->
db->query(
$sql);
1429 $this->error = $this->
db->lasterror();
1433 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def";
1434 $sql .=
" WHERE file = '".$this->db->escape($file).
"'";
1435 $sql .=
" AND entity = ".$conf->entity;
1437 dol_syslog(get_class($this).
"::delete_boxes", LOG_DEBUG);
1438 $resql = $this->
db->query(
$sql);
1440 $this->error = $this->
db->lasterror();
1458 include_once DOL_DOCUMENT_ROOT.
'/core/class/infobox.class.php';
1464 if (is_array($this->cronjobs)) {
1465 dol_syslog(get_class($this).
"::insert_cronjobs", LOG_DEBUG);
1467 foreach ($this->cronjobs as $key => $value) {
1468 $entity = isset($this->cronjobs[$key][
'entity']) ? $this->cronjobs[$key][
'entity'] : $conf->entity;
1469 $label = isset($this->cronjobs[$key][
'label']) ? $this->cronjobs[$key][
'label'] :
'';
1470 $jobtype = isset($this->cronjobs[$key][
'jobtype']) ? $this->cronjobs[$key][
'jobtype'] :
'';
1471 $class = isset($this->cronjobs[$key][
'class']) ? $this->cronjobs[$key][
'class'] :
'';
1472 $objectname = isset($this->cronjobs[$key][
'objectname']) ? $this->cronjobs[$key][
'objectname'] :
'';
1473 $method = isset($this->cronjobs[$key][
'method']) ? $this->cronjobs[$key][
'method'] :
'';
1474 $command = isset($this->cronjobs[$key][
'command']) ? $this->cronjobs[$key][
'command'] :
'';
1475 $parameters = isset($this->cronjobs[$key][
'parameters']) ? $this->cronjobs[$key][
'parameters'] :
'';
1476 $comment = isset($this->cronjobs[$key][
'comment']) ? $this->cronjobs[$key][
'comment'] :
'';
1477 $frequency = isset($this->cronjobs[$key][
'frequency']) ? $this->cronjobs[$key][
'frequency'] :
'';
1478 $unitfrequency = isset($this->cronjobs[$key][
'unitfrequency']) ? $this->cronjobs[$key][
'unitfrequency'] :
'';
1479 $priority = isset($this->cronjobs[$key][
'priority']) ? $this->cronjobs[$key][
'priority'] :
'';
1480 $datestart = isset($this->cronjobs[$key][
'datestart']) ? $this->cronjobs[$key][
'datestart'] :
'';
1481 $dateend = isset($this->cronjobs[$key][
'dateend']) ? $this->cronjobs[$key][
'dateend'] :
'';
1482 $status = isset($this->cronjobs[$key][
'status']) ? $this->cronjobs[$key][
'status'] :
'';
1483 $test = isset($this->cronjobs[$key][
'test']) ? $this->cronjobs[$key][
'test'] :
'';
1486 $sql =
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"cronjob";
1488 $sql .=
" WHERE label = '".$this->db->escape($label).
"'";
1504 $sql .=
" AND entity = ".((int) $entity);
1508 $result = $this->
db->query(
$sql);
1510 $obj = $this->
db->fetch_object($result);
1511 if ($obj->nb == 0) {
1515 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"cronjob (module_name, datec, datestart, dateend, label, jobtype, classesname, objectname, methodename, command, params, note,";
1516 if (is_int($frequency)) {
1517 $sql .=
' frequency,';
1519 if (is_int($unitfrequency)) {
1520 $sql .=
' unitfrequency,';
1522 if (is_int($priority)) {
1523 $sql .=
' priority,';
1525 if (is_int($status)) {
1528 $sql .=
" entity, test)";
1529 $sql .=
" VALUES (";
1530 $sql .=
"'".$this->db->escape(empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class).
"', ";
1531 $sql .=
"'".$this->db->idate($now).
"', ";
1532 $sql .= ($datestart ?
"'".$this->db->idate($datestart).
"'" :
"'".$this->db->idate($now).
"'").
", ";
1533 $sql .= ($dateend ?
"'".$this->db->idate($dateend).
"'" :
"NULL").
", ";
1534 $sql .=
"'".$this->db->escape($label).
"', ";
1535 $sql .=
"'".$this->db->escape($jobtype).
"', ";
1536 $sql .= ($class ?
"'".$this->db->escape($class).
"'" :
"null").
",";
1537 $sql .= ($objectname ?
"'".$this->db->escape($objectname).
"'" :
"null").
",";
1538 $sql .= ($method ?
"'".$this->db->escape($method).
"'" :
"null").
",";
1539 $sql .= ($command ?
"'".$this->db->escape($command).
"'" :
"null").
",";
1540 $sql .= ($parameters ?
"'".$this->db->escape($parameters).
"'" :
"null").
",";
1541 $sql .= ($comment ?
"'".$this->db->escape($comment).
"'" :
"null").
",";
1542 if (is_int($frequency)) {
1543 $sql .=
"'".$this->db->escape($frequency).
"', ";
1545 if (is_int($unitfrequency)) {
1546 $sql .=
"'".$this->db->escape($unitfrequency).
"', ";
1548 if (is_int($priority)) {
1549 $sql .=
"'".$this->db->escape($priority).
"', ";
1551 if (is_int($status)) {
1552 $sql .= ((int) $status).
", ";
1554 $sql .= $entity.
",";
1555 $sql .=
"'".$this->db->escape($test).
"'";
1558 $resql = $this->
db->query(
$sql);
1565 $this->
db->commit();
1567 $this->error = $this->
db->lasterror();
1568 $this->
db->rollback();
1573 $this->error = $this->
db->lasterror();
1596 if (is_array($this->cronjobs)) {
1597 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"cronjob";
1598 $sql .=
" WHERE module_name = '".$this->db->escape(empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class).
"'";
1599 $sql .=
" AND entity = ".$conf->entity;
1600 $sql .=
" AND test = '1'";
1603 dol_syslog(get_class($this).
"::delete_cronjobs", LOG_DEBUG);
1604 $resql = $this->
db->query(
$sql);
1606 $this->error = $this->
db->lasterror();
1627 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
1628 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" like '".$this->
db->escape($this->const_name).
"_TABS_%'";
1629 $sql .=
" AND entity = ".$conf->entity;
1631 dol_syslog(get_class($this).
"::delete_tabs", LOG_DEBUG);
1632 if (!$this->
db->query(
$sql)) {
1633 $this->error = $this->
db->lasterror();
1653 if (!empty($this->tabs)) {
1654 dol_syslog(get_class($this).
"::insert_tabs", LOG_DEBUG);
1657 foreach ($this->tabs as $key => $value) {
1658 if (is_array($value) && count($value) == 0) {
1662 $entity = $conf->entity;
1665 if (is_array($value)) {
1666 $newvalue = $value[
'data'];
1667 if (isset($value[
'entity'])) {
1668 $entity = $value[
'entity'];
1673 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (";
1678 $sql .=
", visible";
1681 $sql .=
" VALUES (";
1682 $sql .= $this->
db->encrypt($this->const_name.
"_TABS_".$i);
1683 $sql .=
", 'chaine'";
1684 $sql .=
", ".$this->db->encrypt($newvalue);
1687 $sql .=
", ".((int) $entity);
1690 $resql = $this->
db->query(
$sql);
1693 if ($this->
db->lasterrno() !=
'DB_ERROR_RECORD_ALREADY_EXISTS') {
1694 $this->error = $this->
db->lasterror();
1695 $this->errors[] = $this->
db->lasterror();
1720 if (empty($this->
const)) {
1724 dol_syslog(get_class($this).
"::insert_const", LOG_DEBUG);
1726 foreach ($this->
const as $key => $value) {
1727 $name = $this->
const[$key][0];
1728 $type = $this->
const[$key][1];
1729 $val = $this->
const[$key][2];
1730 $note = isset($this->
const[$key][3]) ? $this->
const[$key][3] :
'';
1731 $visible = isset($this->
const[$key][4]) ? $this->
const[$key][4] : 0;
1732 $entity = (!empty($this->
const[$key][5]) && $this->
const[$key][5] !=
'current') ? 0 : $conf->entity;
1735 if (empty($visible)) {
1738 if (empty($val) && $val !=
'0') {
1742 $sql =
"SELECT count(*)";
1743 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const";
1744 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($name).
"'";
1745 $sql .=
" AND entity = ".((int) $entity);
1747 $result = $this->
db->query(
$sql);
1749 $row = $this->
db->fetch_row($result);
1752 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name,type,value,note,visible,entity)";
1753 $sql .=
" VALUES (";
1754 $sql .= $this->
db->encrypt($name);
1755 $sql .=
",'".$this->db->escape($type).
"'";
1756 $sql .=
",".(($val !=
'') ? $this->
db->encrypt($val) :
"''");
1757 $sql .=
",".($note ?
"'".$this->db->escape($note).
"'" :
"null");
1758 $sql .=
",'".$this->db->escape($visible).
"'";
1759 $sql .=
",".$entity;
1762 if (!$this->
db->query(
$sql)) {
1766 dol_syslog(get_class($this).
"::insert_const constant '".$name.
"' already exists", LOG_WARNING);
1789 if (empty($this->
const)) {
1793 foreach ($this->
const as $key => $value) {
1794 $name = $this->
const[$key][0];
1795 $deleteonunactive = (!empty($this->
const[$key][6])) ? 1 : 0;
1797 if ($deleteonunactive) {
1798 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
1799 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($name).
"'";
1800 $sql .=
" AND entity in (0, ".$conf->entity.
")";
1801 dol_syslog(get_class($this).
"::delete_const", LOG_DEBUG);
1802 if (!$this->
db->query(
$sql)) {
1803 $this->error = $this->
db->lasterror();
1824 global $conf, $user;
1827 $entity = (!empty($force_entity) ? $force_entity : $conf->entity);
1829 dol_syslog(get_class($this).
"::insert_permissions", LOG_DEBUG);
1832 $sql_del =
"SELECT ".$this->db->decrypt(
'value').
" as value";
1833 $sql_del .=
" FROM ".MAIN_DB_PREFIX.
"const";
1834 $sql_del .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($this->const_name).
"'";
1835 $sql_del .=
" AND entity IN (0,".$entity.
")";
1837 $resql = $this->
db->query($sql_del);
1840 $obj = $this->
db->fetch_object($resql);
1842 if ($obj !==
null && !empty($obj->value) && !empty($this->rights)) {
1843 include_once DOL_DOCUMENT_ROOT.
'/user/class/user.class.php';
1846 foreach ($this->rights as $key => $value) {
1847 $r_id = $this->rights[$key][0];
1848 $r_desc = $this->rights[$key][1];
1849 $r_type = isset($this->rights[$key][2]) ? $this->rights[$key][2] :
'';
1850 $r_def = empty($this->rights[$key][3]) ? 0 : $this->rights[$key][3];
1851 $r_perms = $this->rights[$key][4];
1852 $r_subperms = isset($this->rights[$key][5]) ? $this->rights[$key][5] :
'';
1853 $r_modul = empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class;
1855 if (empty($r_type)) {
1860 $sql =
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"rights_def";
1861 $sql .=
" WHERE id = ".((int) $r_id).
" AND entity = ".((int) $entity);
1863 $resqlselect = $this->
db->query(
$sql);
1865 $objcount = $this->
db->fetch_object($resqlselect);
1866 if ($objcount && $objcount->nb == 0) {
1869 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"rights_def";
1870 $sql .=
" (id, entity, libelle, module, type, bydefault, perms, subperms)";
1872 $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).
"')";
1874 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"rights_def";
1875 $sql .=
" (id, entity, libelle, module, type, bydefault, perms)";
1877 $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).
"')";
1880 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"rights_def ";
1881 $sql .=
" (id, entity, libelle, module, type, bydefault)";
1883 $sql .=
"(".$r_id.
",".$entity.
",'".$this->
db->escape($r_desc).
"','".$this->
db->escape($r_modul).
"','".$this->
db->escape($r_type).
"',".$r_def.
")";
1886 $resqlinsert = $this->
db->query(
$sql, 1);
1888 if (!$resqlinsert) {
1889 if ($this->
db->errno() !=
"DB_ERROR_RECORD_ALREADY_EXISTS") {
1890 $this->error = $this->
db->lasterror();
1894 dol_syslog(get_class($this).
"::insert_permissions record already exists", LOG_INFO);
1898 $this->
db->free($resqlinsert);
1901 $this->
db->free($resqlselect);
1905 if ($reinitadminperms) {
1906 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"user WHERE admin = 1";
1907 dol_syslog(get_class($this).
"::insert_permissions Search all admin users", LOG_DEBUG);
1909 $resqlseladmin = $this->
db->query(
$sql, 1);
1911 if ($resqlseladmin) {
1912 $num = $this->
db->num_rows($resqlseladmin);
1915 $obj2 = $this->
db->fetch_object($resqlseladmin);
1916 dol_syslog(get_class($this).
"::insert_permissions Add permission id ".$r_id.
" to user id=".$obj2->rowid);
1918 $tmpuser =
new User($this->
db);
1919 $result = $tmpuser->fetch($obj2->rowid);
1921 $tmpuser->addrights($r_id,
'',
'', 0, 1);
1923 dol_syslog(get_class($this).
"::insert_permissions Failed to add the permission to user because fetch return an error", LOG_ERR);
1933 if ($reinitadminperms && !empty($user->admin)) {
1935 $user->clearrights();
1939 $this->
db->free($resql);
1941 $this->error = $this->
db->lasterror();
1962 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def";
1963 $sql .=
" WHERE module = '".$this->db->escape(empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class).
"'";
1964 $sql .=
" AND entity = ".$conf->entity;
1965 dol_syslog(get_class($this).
"::delete_permissions", LOG_DEBUG);
1966 if (!$this->
db->query(
$sql)) {
1967 $this->error = $this->
db->lasterror();
1986 if (!is_array($this->menu) || empty($this->menu)) {
1990 include_once DOL_DOCUMENT_ROOT.
'/core/class/menubase.class.php';
1992 dol_syslog(get_class($this).
"::insert_menus", LOG_DEBUG);
1998 foreach ($this->menu as $key => $value) {
2000 $menu->menu_handler =
'all';
2003 $menu->module = (empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class);
2005 if (!$this->menu[$key][
'fk_menu']) {
2009 $fk_parent = $this->menu[$key][
'fk_menu'];
2011 if (preg_match(
'/^r=/', $fk_parent)) {
2012 $fk_parent = str_replace(
'r=',
'', $fk_parent);
2013 if (isset($this->menu[$fk_parent][
'rowid'])) {
2014 $menu->fk_menu = $this->menu[$fk_parent][
'rowid'];
2017 } elseif (preg_match(
'/^fk_mainmenu=([a-zA-Z0-9_]+),fk_leftmenu=([a-zA-Z0-9_]+)$/', $fk_parent, $reg)) {
2018 $menu->fk_menu = -1;
2019 $menu->fk_mainmenu = $reg[1];
2020 $menu->fk_leftmenu = $reg[2];
2022 } elseif (preg_match(
'/^fk_mainmenu=([a-zA-Z0-9_]+)$/', $fk_parent, $reg)) {
2023 $menu->fk_menu = -1;
2024 $menu->fk_mainmenu = $reg[1];
2025 $menu->fk_leftmenu =
'';
2028 if (!$foundparent) {
2029 $this->error =
"ErrorBadDefinitionOfMenuArrayInModuleDescriptor";
2030 dol_syslog(get_class($this).
"::insert_menus ".$this->error.
" ".$this->menu[$key][
'fk_menu'], LOG_ERR);
2034 $menu->type = $this->menu[$key][
'type'];
2035 $menu->mainmenu = isset($this->menu[$key][
'mainmenu']) ? $this->menu[$key][
'mainmenu'] : (isset($menu->fk_mainmenu) ? $menu->fk_mainmenu :
'');
2036 $menu->leftmenu = isset($this->menu[$key][
'leftmenu']) ? $this->menu[$key][
'leftmenu'] :
'';
2037 $menu->title = $this->menu[$key][
'titre'];
2038 $menu->prefix = isset($this->menu[$key][
'prefix']) ? $this->menu[$key][
'prefix'] :
'';
2039 $menu->url = $this->menu[$key][
'url'];
2040 $menu->langs = isset($this->menu[$key][
'langs']) ? $this->menu[$key][
'langs'] :
'';
2041 $menu->position = $this->menu[$key][
'position'];
2042 $menu->perms = $this->menu[$key][
'perms'];
2043 $menu->target = isset($this->menu[$key][
'target']) ? $this->menu[$key][
'target'] :
'';
2044 $menu->user = $this->menu[$key][
'user'];
2045 $menu->enabled = isset($this->menu[$key][
'enabled']) ? $this->menu[$key][
'enabled'] : 0;
2046 $menu->position = $this->menu[$key][
'position'];
2049 $result = $menu->create($user);
2051 $this->menu[$key][
'rowid'] = $result;
2053 $this->error = $menu->error;
2054 dol_syslog(get_class($this).
'::insert_menus result='.$result.
" ".$this->error, LOG_ERR);
2062 $this->
db->commit();
2064 dol_syslog(get_class($this).
"::insert_menus ".$this->error, LOG_ERR);
2065 $this->
db->rollback();
2086 $module = empty($this->rights_class) ?strtolower($this->
name) : $this->rights_class;
2088 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"menu";
2089 $sql .=
" WHERE module = '".$this->db->escape($module).
"'";
2090 $sql .=
" AND entity = ".$conf->entity;
2092 dol_syslog(get_class($this).
"::delete_menus", LOG_DEBUG);
2093 $resql = $this->
db->query(
$sql);
2095 $this->error = $this->
db->lasterror();
2111 global $langs, $conf;
2115 if (isset($this->dirs) && is_array($this->dirs)) {
2116 foreach ($this->dirs as $key => $value) {
2119 if (!is_array($value)) {
2122 $constname = $this->const_name.
"_DIR_";
2123 $dir = $this->dirs[$key][1];
2124 $addtodatabase = empty($this->dirs[$key][2]) ?
'' : $this->dirs[$key][2];
2125 $subname = empty($this->dirs[$key][3]) ?
'' : strtoupper($this->dirs[$key][3]);
2126 $forcename = empty($this->dirs[$key][4]) ?
'' : strtoupper($this->dirs[$key][4]);
2128 if (!empty($forcename)) {
2129 $constname =
'MAIN_MODULE_'.$forcename.
"_DIR_";
2131 if (!empty($subname)) {
2132 $constname = $constname.$subname.
"_";
2135 $name = $constname.strtoupper($this->dirs[$key][0]);
2139 if (empty($conf->global->MAIN_MODULE_MULTICOMPANY) || $conf->entity == 1) {
2140 $fulldir = DOL_DATA_ROOT.$dir;
2142 $fulldir = DOL_DATA_ROOT.
"/".$conf->entity.$dir;
2145 if (!empty($fulldir) && !file_exists($fulldir)) {
2146 if (
dol_mkdir($fulldir, DOL_DATA_ROOT) < 0) {
2147 $this->error = $langs->trans(
"ErrorCanNotCreateDir", $fulldir);
2148 dol_syslog(get_class($this).
"::_init ".$this->error, LOG_ERR);
2154 if (!empty($addtodatabase)) {
2183 $sql =
"SELECT count(*)";
2184 $sql .=
" FROM ".MAIN_DB_PREFIX.
"const";
2185 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->
db->escape($name).
"'";
2186 $sql .=
" AND entity = ".$conf->entity;
2188 dol_syslog(get_class($this).
"::insert_dirs", LOG_DEBUG);
2189 $result = $this->
db->query(
$sql);
2191 $row = $this->
db->fetch_row($result);
2194 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name, type, value, note, visible, entity)";
2195 $sql .=
" VALUES (".$this->db->encrypt($name).
", 'chaine', ".$this->
db->encrypt($dir).
", '".$this->
db->escape(
"Directory for module ".$this->
name).
"', '0', ".((int) $conf->entity).
")";
2197 dol_syslog(get_class($this).
"::insert_dirs", LOG_DEBUG);
2201 $this->error = $this->
db->lasterror();
2222 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
2223 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" LIKE '".$this->
db->escape($this->const_name).
"_DIR_%'";
2224 $sql .=
" AND entity = ".$conf->entity;
2226 dol_syslog(get_class($this).
"::delete_dirs", LOG_DEBUG);
2227 if (!$this->
db->query(
$sql)) {
2228 $this->error = $this->
db->lasterror();
2248 if (is_array($this->module_parts) && !empty($this->module_parts)) {
2249 foreach ($this->module_parts as $key => $value) {
2250 if (is_array($value) && count($value) == 0) {
2254 $entity = $conf->entity;
2258 if (is_array($value)) {
2261 if (isset($value[
'data']) && is_array($value[
'data'])) {
2262 $newvalue = json_encode($value[
'data']);
2263 if (isset($value[
'entity'])) {
2264 $entity = $value[
'entity'];
2266 } elseif (isset($value[
'data']) && !is_array($value[
'data'])) {
2267 $newvalue = $value[
'data'];
2268 if (isset($value[
'entity'])) {
2269 $entity = $value[
'entity'];
2272 $newvalue = json_encode($value);
2276 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"const (";
2281 $sql .=
", visible";
2284 $sql .=
" VALUES (";
2285 $sql .=
" ".$this->db->encrypt($this->const_name.
"_".strtoupper($key));
2286 $sql .=
", 'chaine'";
2287 $sql .=
", ".$this->db->encrypt($newvalue);
2290 $sql .=
", ".((int) $entity);
2293 dol_syslog(get_class($this).
"::insert_module_parts for key=".$this->const_name.
"_".strtoupper($key), LOG_DEBUG);
2295 $resql = $this->
db->query(
$sql, 1);
2297 if ($this->
db->lasterrno() !=
'DB_ERROR_RECORD_ALREADY_EXISTS') {
2299 $this->error = $this->
db->lasterror();
2301 dol_syslog(get_class($this).
"::insert_module_parts for ".$this->const_name.
"_".strtoupper($key).
" Record already exists.", LOG_WARNING);
2321 $entity = $conf->entity;
2323 if (is_array($this->module_parts) && !empty($this->module_parts)) {
2324 dol_syslog(get_class($this).
"::delete_module_parts", LOG_DEBUG);
2326 foreach ($this->module_parts as $key => $value) {
2328 if (is_array($value) && isset($value[
'entity'])) {
2329 $entity = $value[
'entity'];
2332 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
2333 $sql .=
" WHERE ".$this->db->decrypt(
'name').
" LIKE '".$this->
db->escape($this->const_name).
"_".strtoupper($key).
"'";
2334 $sql .=
" AND entity = ".((int) $entity);
2336 if (!$this->
db->query(
$sql)) {
2337 $this->error = $this->
db->lasterror();
2354 public function init($options =
'')
2356 return $this->
_init(array(), $options);
2367 public function remove($options =
'')
2369 return $this->
_remove(array(), $options);
2382 global $conf, $langs;
2387 $imginfo =
"info_black";
2390 $const_name =
'MAIN_MODULE_'.strtoupper(preg_replace(
'/^mod/i',
'', get_class($this)));
2394 if (preg_match(
'/development/i', $version)) {
2395 $versiontrans .=
'warning';
2397 if (preg_match(
'/experimental/i', $version)) {
2398 $versiontrans .=
'warning';
2400 if (preg_match(
'/deprecated/i', $version)) {
2401 $versiontrans .=
'warning';
2405 <div class="box-flex-item info-box-module'
2406 .(empty($conf->global->$const_name) ?
' --disabled' :
'')
2408 .($this->needUpdate ?
' --need-update' :
'')
2410 <div class="info-box info-box-sm info-box-module">
2411 <div class="info-box-icon'.(empty($conf->global->$const_name) ?
'' :
' info-box-icon-module-enabled'.($versiontrans ?
' info-box-icon-module-warning' :
'')).
'">';
2416 if (!empty($this->picto)) {
2417 if (preg_match(
'/^\//i', $this->picto)) {
2418 print
img_picto($alttext, $this->picto,
'class="inline-block valignmiddle"', 1);
2420 print
img_object($alttext, $this->picto,
'class="inline-block valignmiddle"');
2423 print
img_object($alttext,
'generic',
'class="inline-block valignmiddle"');
2426 if ($this->
isCoreOrExternalModule() ==
'external' || preg_match(
'/development|experimental|deprecated/i', $version)) {
2427 $versionTitle = $langs->trans(
"Version").
' '.$this->
getVersion(1);
2428 if ($this->needUpdate) {
2429 $versionTitle.=
'<br>'.$langs->trans(
'ModuleUpdateAvailable').
' : '.
$this->lastVersion;
2432 print
'<span class="info-box-icon-version'.($versiontrans ?
' '.$versiontrans :
'').
' classfortooltip" title="'.
dol_escape_js($versionTitle).
'" >';
2438 <div class="info-box-content info-box-text-module'.(empty($conf->global->$const_name) ?
'' :
' info-box-module-enabled'.($versiontrans ?
' info-box-content-warning' :
'')).
'">
2439 <span class="info-box-title">'.$this->
getName().
'</span>
2442 print
'<div class="valignmiddle inline-block info-box-more">';
2444 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>';
2447 print '<div class="valignmiddle
inline-block info-box-actions
">';
2448 print '<div class="valignmiddle
inline-block info-box-setup
">';
2449 print $codetoconfig;
2451 print '<div class="valignmiddle
inline-block marginleftonly marginrightonly
">';
2452 print $codeenabledisable;
2457 </div><!-- /.info-box-content -->
2458 </div><!-- /.info-box -->
2469 public function checkForUpdate()
2471 require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
2472 if (!empty($this->url_last_version)) {
2473 $lastVersion = getURLContent($this->url_last_version, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
2474 if (isset($lastVersion['content']) && strlen($lastVersion['content']) < 30) {
2475 // 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 _ . -
2476 $this->lastVersion = preg_replace("/[^a-zA-Z0-9_\.\-]+/
", "", $lastVersion['content']);
2477 if (version_compare($this->lastVersion, $this->version) > 0) {
2478 $this->needUpdate = true;
2481 $this->needUpdate = false;