64  public $editor_squarred_logo;
 
   92  public $module_position = 
'50';
 
  109  public $dirs = array();
 
  114  public $boxes = array();
 
  120  public $const = array();
 
  125  public $cronjobs = array();
 
  135  public $rights_admin_allowed;
 
  140  public $rights_class;
 
  142  const URL_FOR_BLACKLISTED_MODULES = 
'https://ping.dolibarr.org/modules-blacklist.txt';
 
  147  const KEY_DEFAULT = 3;
 
  148  const KEY_FIRST_LEVEL = 4;
 
  149  const KEY_SECOND_LEVEL = 5;
 
  150  const KEY_MODULE = 6;
 
  151  const KEY_ENABLED = 7;
 
  156  public $menu = array();
 
  185  public $module_parts = array();
 
  234  public $descriptionlong;
 
  239  public $dictionaries = array();
 
  256  public $export_label;
 
  266  public $export_enabled;
 
  270  public $export_permission;
 
  274  public $export_fields_array;
 
  278  public $export_TypeFields_array; 
 
  282  public $export_entities_array;
 
  286  public $export_aggregate_array;
 
  290  public $export_examplevalues_array;
 
  294  public $export_help_array;
 
  301  public $export_special_array; 
 
  308  public $export_dependencies_array;
 
  312  public $export_sql_start;
 
  316  public $export_sql_end;
 
  320  public $export_sql_order;
 
  333  public $import_label;
 
  342  public $import_entities_array;
 
  346  public $import_tables_array;
 
  350  public $import_tables_creator_array;
 
  354  public $import_fields_array;
 
  358  public $import_fieldshidden_array;
 
  362  public $import_convertvalue_array;
 
  366  public $import_regex_array;
 
  370  public $import_examplevalues_array;
 
  374  public $import_updatekeys_array;
 
  378  public $import_run_sql_after_array;
 
  382  public $import_TypeFields_array;
 
  386  public $import_help_array;
 
  396  public $always_enabled;
 
  406  public $core_enabled;
 
  422  public $config_page_url;
 
  445  public $conflictwith;
 
  457  public $warnings_activation;
 
  464  public $warnings_activation_ext;
 
  471  public $warnings_unactivation;
 
  488  public $need_dolibarr_version;
 
  493  public $need_javascript_ajax;
 
  498  public $enabled_bydefault;
 
  503  public $hidden = 
false;
 
  508  public $url_last_version;
 
  537  protected function _init($array_sql, $options = 
'')
 
  561    if (!$err && !preg_match(
'/newboxdefonly/', $options)) {
 
  566    if (!$err && !preg_match(
'/noboxes/', $options)) {
 
  591    $num = count($array_sql);
 
  592    for ($i = 0; $i < $num; $i++) {
 
  594        $val = $array_sql[$i];
 
  597        if (is_array($val)) {
 
  599          $ignoreerror = $val[
'ignoreerror'];
 
  602        $sql = str_replace(
'__ENTITY__', (
string) 
$conf->entity, $sql);
 
  604        dol_syslog(get_class($this).
"::_init ignoreerror=".$ignoreerror, LOG_DEBUG);
 
  605        $result = $this->db->query($sql, $ignoreerror);
 
  608            $this->error = $this->db->lasterror();
 
  611            dol_syslog(get_class($this).
"::_init Warning ".$this->db->lasterror(), LOG_WARNING);
 
  621      $moduleNameInConf = strtolower(preg_replace(
'/^MAIN_MODULE_/', 
'', $this->const_name));
 
  623      if ($moduleNameInConf === 
'propale') {
 
  624        $moduleNameInConf = 
'propal';
 
  625      } elseif ($moduleNameInConf === 
'supplierproposal') {
 
  626        $moduleNameInConf = 
'supplier_proposal';
 
  629      $conf->modules[$moduleNameInConf] = $moduleNameInConf; 
 
  633      $this->db->rollback();
 
 
  647  protected function _remove($array_sql, $options = 
'')
 
  676    if (!$err && !preg_match(
'/(newboxdefonly|noboxes)/', $options)) {
 
  701    $num = count((array) $array_sql);
 
  702    for ($i = 0; $i < $num; $i++) {
 
  704        dol_syslog(get_class($this).
"::_remove", LOG_DEBUG);
 
  705        $result = $this->db->query($array_sql[$i]);
 
  707          $this->error = $this->db->error();
 
  718      $moduleNameInConf = strtolower(preg_replace(
'/^MAIN_MODULE_/', 
'', $this->const_name));
 
  720      if ($moduleNameInConf === 
'propale') {
 
  721        $moduleNameInConf = 
'propal';
 
  722      } elseif ($moduleNameInConf === 
'supplierproposal') {
 
  723        $moduleNameInConf = 
'supplier_proposal';
 
  726      unset(
$conf->modules[$moduleNameInConf]); 
 
  730      $this->db->rollback();
 
 
  745    $langs->load(
"admin");
 
  747    if ($langs->transnoentitiesnoconv(
"Module".$this->numero.
"Name") != 
"Module".$this->numero.
"Name") {
 
  749      return $langs->transnoentitiesnoconv(
"Module".$this->numero.
"Name");
 
  752      if (is_array($this->langfiles)) {
 
  753        foreach ($this->langfiles as $val) {
 
  760      if ($langs->trans(
"Module".$this->name.
"Name") != 
"Module".$this->name.
"Name") {
 
  762        return $langs->transnoentitiesnoconv(
"Module".$this->
name.
"Name");
 
  766      return $langs->transnoentitiesnoconv($this->
name);
 
 
  779    $langs->load(
"admin");
 
  781    if ($langs->transnoentitiesnoconv(
"Module".$this->numero.
"Desc") != 
"Module".$this->numero.
"Desc") {
 
  783      return $langs->transnoentitiesnoconv(
"Module".$this->numero.
"Desc");
 
  786      if (is_array($this->langfiles)) {
 
  787        foreach ($this->langfiles as $val) {
 
  794      if ($langs->transnoentitiesnoconv(
"Module".$this->name.
"Desc") != 
"Module".$this->name.
"Desc") {
 
  796        return $langs->trans(
"Module".$this->
name.
"Desc");
 
 
  813    $langs->load(
"admin");
 
  815    include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
 
  816    include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
 
  822      $content = file_get_contents($pathoffile, 
false, 
null, 0, 1024 * 1024); 
 
  824      if ((
float) DOL_VERSION >= 6.0) {  
 
  825        @include_once DOL_DOCUMENT_ROOT.
'/core/lib/parsemd.lib.php';
 
  837        $content = preg_replace(
'/<a href="/', 
'<a target="_blank" rel="noopener noreferrer" href="', $content);
 
  839        $content = nl2br($content);
 
  843      if (!empty($this->descriptionlong)) {
 
  844        if (is_array($this->langfiles)) {
 
  845          foreach ($this->langfiles as $val) {
 
  852        $content = $langs->transnoentitiesnoconv($this->descriptionlong);
 
  856    return '<div class="moduledesclong">'.$content.
'</div>';
 
 
  872    $pathoffile = 
dol_buildpath(strtolower($this->
name).
'/README-'.$langs->defaultlang.
'.md', 0);
 
  877      $tmp = explode(
'_', $langs->defaultlang);
 
  878      $pathoffile = 
dol_buildpath(strtolower($this->
name).
'/README-'.$tmp[0].
'.md', 0);
 
  890    return ($filefound ? $pathoffile : 
'');
 
 
  902    $langs->load(
"admin");
 
  904    include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
 
  905    include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
 
  911    $pathoffile = 
dol_buildpath(strtolower($this->
name).
'/ChangeLog-'.$langs->defaultlang.
'.md', 0);
 
  923      $content = file_get_contents($pathoffile);
 
  925      if ((
float) DOL_VERSION >= 6.0) {  
 
  926        @include_once DOL_DOCUMENT_ROOT.
'/core/lib/parsemd.lib.php';
 
  930        $content = nl2br($content);
 
 
  946    return $this->editor_name;
 
 
  956    return $this->editor_url;
 
 
  970    $langs->load(
"admin");
 
  974    $newversion = preg_replace(
'/_deprecated/', 
'', $this->version);
 
  975    if ($newversion == 
'experimental') {
 
  976      $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionExperimental") : $newversion);
 
  977    } elseif ($newversion == 
'development') {
 
  978      $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionDevelopment") : $newversion);
 
  979    } elseif ($newversion == 
'dolibarr') {
 
  981    } elseif ($newversion) {
 
  984      $ret = ($translated ? $langs->transnoentitiesnoconv(
"VersionUnknown") : 
'unknown');
 
  987    if (preg_match(
'/_deprecated/', $this->version)) {
 
  988      $ret .= ($translated ? 
' ('.$langs->transnoentitiesnoconv(
"Deprecated").
')' : $this->version);
 
 
 1000    if (in_array($this->version, array(
'dolibarr', 
'dolibarr_deprecated', 
'experimental', 
'development'))) {  
 
 1001      return $this->module_position;
 
 1003      if ($this->module_position >= 100000) {
 
 1004        return $this->module_position;
 
 1006        $position = intval($this->module_position) + 100000;
 
 1007        return strval($position);
 
 
 1020    if ($this->version == 
'dolibarr' || $this->version == 
'dolibarr_deprecated') {
 
 1023    if (!empty($this->version) && !in_array($this->version, array(
'experimental', 
'development'))) {
 
 1026    if (!empty($this->editor_name) || !empty($this->editor_url)) {
 
 1029    if ($this->numero >= 100000) {
 
 
 1043    return $this->langfiles;
 
 
 1057    $langstring = 
"ExportDataset_".$this->export_code[$r];
 
 1058    if ($langs->trans($langstring) == $langstring) {
 
 1060      return $langs->trans($this->export_label[$r]);
 
 1063      return $langs->trans($langstring);
 
 
 1079    $langstring = 
"ImportDataset_".$this->import_code[$r];
 
 1081    if ($langs->trans($langstring) == $langstring) {
 
 1083      return $langs->transnoentitiesnoconv($this->import_label[$r]);
 
 1086      return $langs->transnoentitiesnoconv($langstring);
 
 
 1102    $sql = 
"SELECT tms FROM ".MAIN_DB_PREFIX.
"const";
 
 1103    $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($this->const_name).
"'";
 
 1104    $sql .= 
" AND entity IN (0, ".((int) 
$conf->entity).
")";
 
 1106    dol_syslog(get_class($this).
"::getLastActiveDate", LOG_DEBUG);
 
 1107    $resql = $this->db->query($sql);
 
 1111      $obj = $this->db->fetch_object($resql);
 
 1113        return $this->db->jdate($obj->tms);
 
 
 1132    $sql = 
"SELECT tms, note FROM ".MAIN_DB_PREFIX.
"const";
 
 1133    $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($this->const_name).
"'";
 
 1134    $sql .= 
" AND entity IN (0, ".$conf->entity.
")";
 
 1136    dol_syslog(get_class($this).
"::getLastActiveDate", LOG_DEBUG);
 
 1137    $resql = $this->db->query($sql);
 
 1141      $obj = $this->db->fetch_object($resql);
 
 1145          $tmp = json_decode($obj->note, 
true);
 
 1148          'authorid' => empty($tmp[
'authorid']) ? 
'' : (int) $tmp[
'authorid'],
 
 1149          'ip' => empty($tmp[
'ip']) ? 
'' : (string) $tmp[
'ip'],
 
 1150          'lastactivationdate' => $this->db->jdate($obj->tms),
 
 1151          'lastactivationversion' => (!empty($tmp[
'lastactivationversion']) ? (string) $tmp[
'lastactivationversion'] : 
'unknown'),
 
 
 1169    global 
$conf, $user;
 
 1174    $entity = ((!empty($this->always_enabled) || !empty($this->core_enabled)) ? 0 : 
$conf->entity);
 
 1176    $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
 
 1177    $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($this->const_name).
"'";
 
 1178    $sql .= 
" AND entity IN (0, ".$entity.
")";
 
 1180    dol_syslog(get_class($this).
"::_active delete activation constant", LOG_DEBUG);
 
 1181    $resql = $this->db->query($sql);
 
 1186    $note = json_encode(
 
 1188        'authorid' => (is_object($user) ? $user->id : 0),
 
 1189        'ip' => (empty($_SERVER[
'REMOTE_ADDR']) ? 
'' : $_SERVER[
'REMOTE_ADDR']),
 
 1190        'lastactivationversion' => $this->version,
 
 1194    $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name, value, visible, entity, note) VALUES";
 
 1195    $sql .= 
" (".$this->db->encrypt($this->const_name);
 
 1196    $sql .= 
", ".$this->db->encrypt(
'1');
 
 1197    $sql .= 
", 0, ".((int) $entity);
 
 1198    $sql .= 
", '".$this->db->escape($note).
"')";
 
 1200    dol_syslog(get_class($this).
"::_active insert activation constant", LOG_DEBUG);
 
 1201    $resql = $this->db->query($sql);
 
 
 1224    $entity = ((!empty($this->always_enabled) || !empty($this->core_enabled)) ? 0 : 
$conf->entity);
 
 1226    $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
 
 1227    $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($this->const_name).
"'";
 
 1228    $sql .= 
" AND entity IN (0, ".$entity.
")";
 
 1230    dol_syslog(get_class($this).
"::_unactive", LOG_DEBUG);
 
 1231    $this->db->query($sql);
 
 
 1262    if (empty($reldir)) {
 
 1266    include_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
 
 1268    foreach (
$conf->file->dol_document_root as $dirroot) {
 
 1270        $dirsql = $dirroot.$reldir;
 
 1274        $listofsubdir = array(
'', 
'tables/', 
'data/');
 
 1275        if ($this->db->type == 
'pgsql') {
 
 1276          $listofsubdir[] = 
'../pgsql/functions/';
 
 1279        foreach ($listofsubdir as $subdir) {
 
 1280          $dir = $dirsql.$subdir;
 
 1282          $handle = @opendir($dir); 
 
 1283          if (is_resource($handle)) {
 
 1288            while (($file = readdir($handle)) !== 
false) {
 
 1292            foreach ($files as $file) {
 
 1293              if ($onlywithsuffix) {
 
 1294                if (!preg_match(
'/\-'.preg_quote($onlywithsuffix, 
'/').
'\./i', $file)) {
 
 1301              if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) == 
'llx_') {
 
 1313            while (($file = readdir($handle)) !== 
false) {
 
 1317            foreach ($files as $file) {
 
 1318              if ($onlywithsuffix) {
 
 1319                if (!preg_match(
'/\-'.preg_quote($onlywithsuffix, 
'/').
'\./i', $file)) {
 
 1326              if (preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) == 
'llx_') {
 
 1338            while (($file = readdir($handle)) !== 
false) {
 
 1342            foreach ($files as $file) {
 
 1343              if ($onlywithsuffix) {
 
 1344                if (!preg_match(
'/\-'.preg_quote($onlywithsuffix, 
'/').
'\./i', $file)) {
 
 1351              if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 9) == 
'functions') {
 
 1363            while (($file = readdir($handle)) !== 
false) {
 
 1367            foreach ($files as $file) {
 
 1368              if ($onlywithsuffix) {
 
 1369                if (!preg_match(
'/\-'.preg_quote($onlywithsuffix, 
'/').
'\./i', $file)) {
 
 1376              if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 4) == 
'data') {
 
 1388            while (($file = readdir($handle)) !== 
false) {
 
 1392            foreach ($files as $file) {
 
 1393              if ($onlywithsuffix) {
 
 1394                if (!preg_match(
'/\-'.preg_quote($onlywithsuffix, 
'/').
'\./i', $file)) {
 
 1401              if (preg_match(
'/\.sql$/i', $file) && !preg_match(
'/\.key\.sql$/i', $file) && substr($file, 0, 6) == 
'update') {
 
 1420      dol_syslog(
"A module wants to load sql files from ".$reldir.
" but this directory was not found.", LOG_WARNING);
 
 
 1437    include_once DOL_DOCUMENT_ROOT.
'/core/class/infobox.class.php';
 
 1443    if (is_array($this->boxes)) {
 
 1444      dol_syslog(get_class($this).
"::insert_boxes", LOG_DEBUG);
 
 1448      foreach ($this->boxes as $key => $value) {
 
 1449        $file  = isset($this->boxes[$key][
'file']) ? $this->boxes[$key][
'file'] : 
'';
 
 1450        $note  = isset($this->boxes[$key][
'note']) ? $this->boxes[$key][
'note'] : 
'';
 
 1451        $enabledbydefaulton = isset($this->boxes[$key][
'enabledbydefaulton']) ? $this->boxes[$key][
'enabledbydefaulton'] : 
'Home';
 
 1454          $file  = isset($this->boxes[$key][1]) ? $this->boxes[$key][1] : 
''; 
 
 1457          $note  = isset($this->boxes[$key][2]) ? $this->boxes[$key][2] : 
''; 
 
 1461        $sql = 
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"boxes_def";
 
 1462        $sql .= 
" WHERE file = '".$this->db->escape($file).
"'";
 
 1463        $sql .= 
" AND entity = ".$conf->entity;
 
 1465          $sql .= 
" AND note ='".$this->db->escape($note).
"'";
 
 1468        $result = $this->db->query($sql);
 
 1470          $obj = $this->db->fetch_object($result);
 
 1471          if ($obj->nb == 0) {
 
 1475              $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"boxes_def (file, entity, note)";
 
 1476              $sql .= 
" VALUES ('".$this->db->escape($file).
"', ";
 
 1477              $sql .= 
$conf->entity.
", ";
 
 1478              $sql .= $note ? 
"'".$this->db->escape($note).
"'" : 
"null";
 
 1481              dol_syslog(get_class($this).
"::insert_boxes", LOG_DEBUG);
 
 1482              $resql = $this->db->query($sql);
 
 1487            if (!$err && !preg_match(
'/newboxdefonly/', $option)) {
 
 1488              $lastid = $this->db->last_insert_id(MAIN_DB_PREFIX.
"boxes_def", 
"rowid");
 
 1490              foreach ($pos_name as $key2 => $val2) {
 
 1492                if ($enabledbydefaulton && $val2 != $enabledbydefaulton) {
 
 1496                $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"boxes (box_id, position, box_order, fk_user, entity)";
 
 1497                $sql .= 
" VALUES (".((int) $lastid).
", ".((int) $key2).
", '0', 0, ".((int) 
$conf->entity).
")";
 
 1499                dol_syslog(get_class($this).
"::insert_boxes onto page ".$key2.
"=".$val2, LOG_DEBUG);
 
 1500                $resql = $this->db->query($sql);
 
 1508              $this->db->commit();
 
 1510              $this->error = $this->db->lasterror();
 
 1511              $this->db->rollback();
 
 1516          $this->error = $this->db->lasterror();
 
 
 1539    if (is_array($this->boxes)) {
 
 1540      foreach ($this->boxes as $key => $value) {
 
 1542        if (empty($this->boxes[$key][
'file'])) {
 
 1543          $file = isset($this->boxes[$key][1]) ? $this->boxes[$key][1] : 
''; 
 
 1545          $file = $this->boxes[$key][
'file'];
 
 1553        if ($file == 
'box_graph_product_distribution.php') {
 
 1554          if (isModEnabled(
"product") || isModEnabled(
"service")) {
 
 1555            dol_syslog(
"We discard deleting module ".$file.
" because another module still active requires it.");
 
 1560        if ($this->db->type == 
'sqlite3') {
 
 1563          $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes ";
 
 1564          $sql .= 
"WHERE ".MAIN_DB_PREFIX.
"boxes.box_id IN (";
 
 1565          $sql .= 
"SELECT ".MAIN_DB_PREFIX.
"boxes_def.rowid ";
 
 1566          $sql .= 
"FROM ".MAIN_DB_PREFIX.
"boxes_def ";
 
 1567          $sql .= 
"WHERE ".MAIN_DB_PREFIX.
"boxes_def.file = '".$this->db->escape($file).
"') ";
 
 1568          $sql .= 
"AND ".MAIN_DB_PREFIX.
"boxes.entity = ".
$conf->entity;
 
 1570          $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes";
 
 1571          $sql .= 
" USING ".MAIN_DB_PREFIX.
"boxes, ".MAIN_DB_PREFIX.
"boxes_def";
 
 1572          $sql .= 
" WHERE ".MAIN_DB_PREFIX.
"boxes.box_id = ".MAIN_DB_PREFIX.
"boxes_def.rowid";
 
 1573          $sql .= 
" AND ".MAIN_DB_PREFIX.
"boxes_def.file = '".$this->db->escape($file).
"'";
 
 1574          $sql .= 
" AND ".MAIN_DB_PREFIX.
"boxes.entity = ".
$conf->entity;
 
 1577        dol_syslog(get_class($this).
"::delete_boxes", LOG_DEBUG);
 
 1578        $resql = $this->db->query($sql);
 
 1580          $this->error = $this->db->lasterror();
 
 1584        $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"boxes_def";
 
 1585        $sql .= 
" WHERE file = '".$this->db->escape($file).
"'";
 
 1586        $sql .= 
" AND entity = ".$conf->entity;   
 
 1588        dol_syslog(get_class($this).
"::delete_boxes", LOG_DEBUG);
 
 1589        $resql = $this->db->query($sql);
 
 1591          $this->error = $this->db->lasterror();
 
 
 1609    include_once DOL_DOCUMENT_ROOT . 
'/core/class/infobox.class.php';
 
 1610    include_once DOL_DOCUMENT_ROOT . 
'/cron/class/cronjob.class.php';
 
 1611    include_once DOL_DOCUMENT_ROOT . 
'/user/class/user.class.php';
 
 1613    global 
$conf, $user;
 
 1616      $user = 
new User($this->db);
 
 1621    if (is_array($this->cronjobs)) {
 
 1622      dol_syslog(get_class($this) . 
"::insert_cronjobs", LOG_DEBUG);
 
 1624      foreach ($this->cronjobs as $key => $value) {
 
 1627        $entity = isset($value[
'entity']) ? $value[
'entity'] : 
$conf->entity;
 
 1628        $label = isset($value[
'label']) ? $value[
'label'] : 
'';
 
 1629        $jobtype = isset($value[
'jobtype']) ? $value[
'jobtype'] : 
'';
 
 1630        $classesname = isset($value[
'class']) ? $value[
'class'] : 
'';
 
 1631        $objectname = isset($value[
'objectname']) ? $value[
'objectname'] : 
'';
 
 1632        $methodename = isset($value[
'method']) ? $value[
'method'] : 
'';
 
 1633        $command = isset($value[
'command']) ? $value[
'command'] : 
'';
 
 1634        $params = isset($value[
'parameters']) ? $value[
'parameters'] : 
'';
 
 1635        $md5params = isset($value[
'md5params']) ? $value[
'md5params'] : 
'';
 
 1636        $comment = isset($value[
'comment']) ? $value[
'comment'] : 
'';
 
 1637        $frequency = isset($value[
'frequency']) ? $value[
'frequency'] : 
'';
 
 1638        $unitfrequency = isset($value[
'unitfrequency']) ? $value[
'unitfrequency'] : 
'';
 
 1639        $priority = isset($value[
'priority']) ? $value[
'priority'] : 
'';
 
 1640        $datestart = isset($value[
'datestart']) ? $value[
'datestart'] : 
'';
 
 1641        $dateend = isset($value[
'dateend']) ? $value[
'dateend'] : 
'';
 
 1642        $datenextrun = isset($value[
'datenextrun']) ? $value[
'datenextrun'] : $now;
 
 1643        $status = isset($value[
'status']) ? $value[
'status'] : 
'';
 
 1644        $maxrun = isset($value[
'maxrun']) ? $value[
'maxrun'] : 0;
 
 1645        $libname = isset($value[
'libname']) ? $value[
'libname'] : 
'';
 
 1646        $test = isset($value[
'test']) ? $value[
'test'] : 
''; 
 
 1649        $sql = 
"SELECT count(*) as nb FROM " . MAIN_DB_PREFIX . 
"cronjob";
 
 1651        $sql .= 
" WHERE label = '".$this->db->escape($label).
"'";
 
 1669        $sql .= 
" AND entity = " . ((int) $entity); 
 
 1671        $result = $this->db->query($sql);
 
 1673          $this->error = $this->db->lasterror();
 
 1679        $obj = $this->db->fetch_object($result);
 
 1684        $cronjob = 
new Cronjob($this->db);
 
 1686        $cronjob->entity = $entity;
 
 1687        $cronjob->label = $label;
 
 1688        $cronjob->jobtype = $jobtype;
 
 1689        $cronjob->classesname = $classesname;
 
 1690        $cronjob->objectname = $objectname;
 
 1691        $cronjob->methodename = $methodename;
 
 1692        $cronjob->command = $command;
 
 1693        $cronjob->params = $params;
 
 1694        $cronjob->md5params = $md5params;
 
 1695        $cronjob->note_private = $comment;
 
 1696        $cronjob->frequency = $frequency;
 
 1697        $cronjob->unitfrequency = $unitfrequency;
 
 1698        $cronjob->priority = $priority;
 
 1699        $cronjob->datestart = $datestart;
 
 1700        $cronjob->dateend = $dateend;
 
 1701        $cronjob->datenextrun = $datenextrun;
 
 1702        $cronjob->maxrun = $maxrun;
 
 1703        $cronjob->status = $status;
 
 1704        $cronjob->test = $test;
 
 1705        $cronjob->libname = $libname;
 
 1706        $cronjob->module_name = empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class;
 
 1708        $retCreate = $cronjob->create($user);
 
 1710        if ($retCreate < 0) {
 
 1711          $this->error = implode(
"\n", array_merge([$cronjob->error], $cronjob->errors));
 
 
 1733    if (is_array($this->cronjobs)) {
 
 1734      $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"cronjob";
 
 1735      $sql .= 
" WHERE module_name = '".$this->db->escape(empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class).
"'";
 
 1736      $sql .= 
" AND entity = ".$conf->entity;
 
 1737      $sql .= 
" AND test = '1'"; 
 
 1740      dol_syslog(get_class($this).
"::delete_cronjobs", LOG_DEBUG);
 
 1741      $resql = $this->db->query($sql);
 
 1743        $this->error = $this->db->lasterror();
 
 
 1764    $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
 
 1765    $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" like '".$this->db->escape($this->const_name).
"_TABS_%'";
 
 1766    $sql .= 
" AND entity = ".$conf->entity;
 
 1768    dol_syslog(get_class($this).
"::delete_tabs", LOG_DEBUG);
 
 1769    if (!$this->db->query($sql)) {
 
 1770      $this->error = $this->db->lasterror();
 
 
 1790    if (!empty($this->tabs)) {
 
 1791      dol_syslog(get_class($this).
"::insert_tabs", LOG_DEBUG);
 
 1794      foreach ($this->tabs as $key => $value) {
 
 1795        if (is_array($value) && count($value) == 0) {
 
 1799        $entity = 
$conf->entity;
 
 1802        if (is_array($value)) {
 
 1803          $newvalue = $value[
'data'];
 
 1804          if (isset($value[
'entity'])) {
 
 1805            $entity = $value[
'entity'];
 
 1810          $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"const (";
 
 1815          $sql .= 
", visible";
 
 1818          $sql .= 
" VALUES (";
 
 1819          $sql .= $this->db->encrypt($this->const_name.
"_TABS_".$i);
 
 1820          $sql .= 
", 'chaine'";
 
 1821          $sql .= 
", ".$this->db->encrypt($newvalue);
 
 1824          $sql .= 
", ".((int) $entity);
 
 1827          $resql = $this->db->query($sql);
 
 1830            if ($this->db->lasterrno() != 
'DB_ERROR_RECORD_ALREADY_EXISTS') {
 
 1831              $this->error = $this->db->lasterror();
 
 1832              $this->errors[] = $this->db->lasterror();
 
 
 1857    if (empty($this->
const)) {
 
 1863    foreach ($this->
const as $key => $value) {
 
 1864      $name      = $this->
const[$key][0];
 
 1865      $type      = $this->
const[$key][1];
 
 1866      $val       = $this->
const[$key][2];
 
 1867      $note      = isset($this->
const[$key][3]) ? $this->
const[$key][3] : 
'';
 
 1868      $visible   = isset($this->
const[$key][4]) ? $this->
const[$key][4] : 0;
 
 1869      $entity    = (!empty($this->
const[$key][5]) && $this->
const[$key][5] != 
'current') ? 0 : 
$conf->entity;
 
 1872      if (empty($visible)) {
 
 1875      if (empty($val) && $val != 
'0') {
 
 1879      $sql = 
"SELECT count(*) as nb";
 
 1880      $sql .= 
" FROM ".MAIN_DB_PREFIX.
"const";
 
 1881      $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($name).
"'";
 
 1882      $sql .= 
" AND entity = ".((int) $entity);
 
 1884      $result = $this->db->query($sql);
 
 1886        $row = $this->db->fetch_row($result);
 
 1889          $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name,type,value,note,visible,entity)";
 
 1890          $sql .= 
" VALUES (";
 
 1891          $sql .= $this->db->encrypt($name);
 
 1892          $sql .= 
",'".$this->db->escape($type).
"'";
 
 1893          $sql .= 
",".(($val != 
'') ? $this->db->encrypt($val) : 
"''");
 
 1894          $sql .= 
",".($note ? 
"'".$this->db->escape($note).
"'" : 
"null");
 
 1895          $sql .= 
",'".$this->db->escape($visible).
"'";
 
 1896          $sql .= 
",".$entity;
 
 1899          if (!$this->db->query($sql)) {
 
 1903          dol_syslog(__METHOD__.
" constant '".$name.
"' already exists", LOG_DEBUG);
 
 
 1926    if (empty($this->
const)) {
 
 1930    foreach ($this->
const as $key => $value) {
 
 1931      $name = $this->
const[$key][0];
 
 1932      $deleteonunactive = (!empty($this->
const[$key][6])) ? 1 : 0;
 
 1934      if ($deleteonunactive) {
 
 1935        $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
 
 1936        $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($name).
"'";
 
 1937        $sql .= 
" AND entity in (0, ".$conf->entity.
")";
 
 1938        dol_syslog(get_class($this).
"::delete_const", LOG_DEBUG);
 
 1939        if (!$this->db->query($sql)) {
 
 1940          $this->error = $this->db->lasterror();
 
 
 1961    global 
$conf, $user;
 
 1964    $entity = (!empty($force_entity) ? $force_entity : 
$conf->entity);
 
 1966    dol_syslog(get_class($this).
"::insert_permissions", LOG_DEBUG);
 
 1969    $sql_del = 
"SELECT ".$this->db->decrypt(
'value').
" as value";
 
 1970    $sql_del .= 
" FROM ".MAIN_DB_PREFIX.
"const";
 
 1971    $sql_del .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($this->const_name).
"'";
 
 1972    $sql_del .= 
" AND entity IN (0,".((int) $entity).
")";
 
 1974    $resql = $this->db->query($sql_del);
 
 1977      $obj = $this->db->fetch_object($resql);
 
 1979      if ($obj !== 
null && !empty($obj->value) && !empty($this->rights)) {
 
 1980        include_once DOL_DOCUMENT_ROOT.
'/user/class/user.class.php';
 
 1994        foreach ($this->rights as $key => $value) {
 
 1995          $r_id = $this->rights[$key][self::KEY_ID];  
 
 1996          $r_label = $this->rights[$key][self::KEY_LABEL];
 
 1997          $r_type = $this->rights[$key][self::KEY_TYPE] ?? 
'w'; 
 
 1998          $r_default = $this->rights[$key][self::KEY_DEFAULT] ?? 0;
 
 1999          $r_perms = $this->rights[$key][self::KEY_FIRST_LEVEL] ?? 
'';
 
 2000          $r_subperms = $this->rights[$key][self::KEY_SECOND_LEVEL] ?? 
'';
 
 2003          if (empty($r_perms)) {
 
 2008          $r_module = (empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class);
 
 2011          $r_module_origin = 
'';
 
 2013          if (isset($this->rights[$key][self::KEY_MODULE])) {
 
 2015            $r_module = $this->rights[$key][self::KEY_MODULE];
 
 2017            $r_module_origin = (empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class);
 
 2021          $r_enabled  = $this->rights[$key][self::KEY_ENABLED] ?? 
'1';
 
 2024          $sql = 
"SELECT count(*) as nb FROM ".MAIN_DB_PREFIX.
"rights_def";
 
 2025          $sql .= 
" WHERE entity = ".((int) $entity);
 
 2026          $sql .= 
" AND id = ".((int) $r_id);
 
 2028          $resqlselect = $this->db->query($sql);
 
 2030            $objcount = $this->db->fetch_object($resqlselect);
 
 2031            if ($objcount && $objcount->nb == 0) {
 
 2032              $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"rights_def (";
 
 2035              $sql .= 
", libelle";
 
 2037              $sql .= 
", module_origin";
 
 2039              $sql .= 
", bydefault";
 
 2041              $sql .= 
", subperms";
 
 2042              $sql .= 
", enabled";
 
 2043              $sql .= 
") VALUES (";
 
 2044              $sql .= ((int) $r_id);
 
 2045              $sql .= 
", ".((int) $entity);
 
 2046              $sql .= 
", '".$this->db->escape($r_label).
"'";
 
 2047              $sql .= 
", '".$this->db->escape($r_module).
"'";
 
 2048              $sql .= 
", '".$this->db->escape($r_module_origin).
"'";
 
 2049              $sql .= 
", '".$this->db->escape($r_type).
"'"; 
 
 2050              $sql .= 
", ".((int) $r_default);
 
 2051              $sql .= 
", '".$this->db->escape($r_perms).
"'";
 
 2052              $sql .= 
", '".$this->db->escape($r_subperms).
"'";
 
 2053              $sql .= 
", '".$this->db->escape($r_enabled).
"'";
 
 2056              $resqlinsert = $this->db->query($sql, 1);
 
 2058              if (!$resqlinsert) {
 
 2059                if ($this->db->errno() != 
"DB_ERROR_RECORD_ALREADY_EXISTS") {
 
 2060                  $this->error = $this->db->lasterror();
 
 2064                  dol_syslog(get_class($this).
"::insert_permissions record already exists", LOG_INFO);
 
 2068              $this->db->free($resqlinsert);
 
 2071            $this->db->free($resqlselect);
 
 2075          if (!empty($reinitadminperms)) {
 
 2076            $sql = 
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"user WHERE admin = 1";
 
 2077            dol_syslog(get_class($this).
"::insert_permissions Search all admin users", LOG_DEBUG);
 
 2079            $resqlseladmin = $this->db->query($sql, 1);
 
 2081            if ($resqlseladmin) {
 
 2082              $num = $this->db->num_rows($resqlseladmin);
 
 2085                $obj2 = $this->db->fetch_object($resqlseladmin);
 
 2086                dol_syslog(get_class($this).
"::insert_permissions Add permission id ".$r_id.
" to user id=".$obj2->rowid);
 
 2088                $tmpuser = 
new User($this->db);
 
 2089                $result = $tmpuser->fetch($obj2->rowid);
 
 2091                  $tmpuser->addrights($r_id, 
'', 
'', 0, 1);
 
 2093                  dol_syslog(get_class($this).
"::insert_permissions Failed to add the permission to user because fetch return an error", LOG_ERR);
 
 2103        if (!empty($reinitadminperms) && !empty($user->admin)) {  
 
 2105          $user->clearrights();
 
 2106          $user->loadRights();
 
 2109      $this->db->free($resql);
 
 2111      $this->error = $this->db->lasterror();
 
 
 2132    $module = empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class;
 
 2134    $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"rights_def";
 
 2135    $sql .= 
" WHERE (module = '".$this->db->escape($module).
"' OR module_origin = '".$this->db->escape($module).
"')";
 
 2138    if (empty($this->core_enabled)) {
 
 2139      $sql .= 
" AND entity = ".((int) 
$conf->entity);
 
 2142    dol_syslog(get_class($this).
"::delete_permissions", LOG_DEBUG);
 
 2143    if (!$this->db->query($sql)) {
 
 2144      $this->error = $this->db->lasterror();
 
 
 2161    global 
$conf, $user;
 
 2163    if (!is_array($this->menu) || empty($this->menu)) {
 
 2167    include_once DOL_DOCUMENT_ROOT.
'/core/class/menubase.class.php';
 
 2169    dol_syslog(get_class($this).
"::insert_menus", LOG_DEBUG);
 
 2174    $entity = ((!empty($this->always_enabled) || !empty($this->core_enabled)) ? 0 : 
$conf->entity);
 
 2178    foreach ($this->menu as $key => $value) {
 
 2180      $menu->menu_handler = 
'all';
 
 2183      $menu->module = (empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class);
 
 2185      if (!$this->menu[$key][
'fk_menu']) {
 
 2189        $fk_parent = $this->menu[$key][
'fk_menu'];
 
 2191        if (preg_match(
'/^r=/', $fk_parent)) {    
 
 2192          $fk_parent = str_replace(
'r=', 
'', $fk_parent);
 
 2193          if (isset($this->menu[$fk_parent][
'rowid'])) {
 
 2194            $menu->fk_menu = $this->menu[$fk_parent][
'rowid'];
 
 2197        } elseif (preg_match(
'/^fk_mainmenu=([a-zA-Z0-9_]+),fk_leftmenu=([a-zA-Z0-9_]+)$/', $fk_parent, $reg)) {
 
 2198          $menu->fk_menu = -1;
 
 2199          $menu->fk_mainmenu = $reg[1];
 
 2200          $menu->fk_leftmenu = $reg[2];
 
 2202        } elseif (preg_match(
'/^fk_mainmenu=([a-zA-Z0-9_]+)$/', $fk_parent, $reg)) {
 
 2203          $menu->fk_menu = -1;
 
 2204          $menu->fk_mainmenu = $reg[1];
 
 2205          $menu->fk_leftmenu = 
'';
 
 2208        if (!$foundparent) {
 
 2209          $this->error = 
"ErrorBadDefinitionOfMenuArrayInModuleDescriptor";
 
 2210          dol_syslog(get_class($this).
"::insert_menus ".$this->error.
" ".$this->menu[$key][
'fk_menu'], LOG_ERR);
 
 2214      $menu->type = $this->menu[$key][
'type'];
 
 2215      $menu->mainmenu = isset($this->menu[$key][
'mainmenu']) ? $this->menu[$key][
'mainmenu'] : (isset($menu->fk_mainmenu) ? $menu->fk_mainmenu : 
'');
 
 2216      $menu->leftmenu = isset($this->menu[$key][
'leftmenu']) ? $this->menu[$key][
'leftmenu'] : 
'';
 
 2217      $menu->title = $this->menu[$key][
'titre'];
 
 2218      $menu->prefix = isset($this->menu[$key][
'prefix']) ? $this->menu[$key][
'prefix'] : 
'';
 
 2219      $menu->url = $this->menu[$key][
'url'];
 
 2220      $menu->langs = isset($this->menu[$key][
'langs']) ? $this->menu[$key][
'langs'] : 
'';
 
 2221      $menu->position = $this->menu[$key][
'position'];
 
 2222      $menu->perms = $this->menu[$key][
'perms'];
 
 2223      $menu->target = isset($this->menu[$key][
'target']) ? $this->menu[$key][
'target'] : 
'';
 
 2224      $menu->user = $this->menu[$key][
'user'];
 
 2225      $menu->enabled = isset($this->menu[$key][
'enabled']) ? $this->menu[$key][
'enabled'] : 0;
 
 2226      $menu->position = $this->menu[$key][
'position'];
 
 2227      $menu->entity = $entity;
 
 2230        $result = $menu->create($user); 
 
 2232          $this->menu[$key][
'rowid'] = $result;
 
 2234          $this->error = $menu->error;
 
 2235          dol_syslog(get_class($this).
'::insert_menus result='.$result.
" ".$this->error, LOG_ERR);
 
 2243      $this->db->commit();
 
 2245      dol_syslog(get_class($this).
"::insert_menus ".$this->error, LOG_ERR);
 
 2246      $this->db->rollback();
 
 
 2267    $module = empty($this->rights_class) ? strtolower($this->
name) : $this->rights_class;
 
 2269    $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"menu";
 
 2270    $sql .= 
" WHERE module = '".$this->db->escape($module).
"'";
 
 2271    $sql .= 
" AND menu_handler = 'all'";  
 
 2272    $sql .= 
" AND entity IN (0, ".$conf->entity.
")";
 
 2274    dol_syslog(get_class($this).
"::delete_menus", LOG_DEBUG);
 
 2275    $resql = $this->db->query($sql);
 
 2277      $this->error = $this->db->lasterror();
 
 
 2293    global $langs, 
$conf;
 
 2298    if (isset($this->dirs) && is_array($this->dirs)) {
 
 2299      foreach ($this->dirs as $key => $value) {
 
 2302        if (!is_array($value)) {
 
 2305          $constname = $this->const_name.
"_DIR_";
 
 2306          $dir       = $this->dirs[$key][1];
 
 2307          $addtodatabase = empty($this->dirs[$key][2]) ? 
'' : $this->dirs[$key][2]; 
 
 2308          $subname   = empty($this->dirs[$key][3]) ? 
'' : strtoupper($this->dirs[$key][3]); 
 
 2309          $forcename = empty($this->dirs[$key][4]) ? 
'' : strtoupper($this->dirs[$key][4]); 
 
 2311          if (!empty($forcename)) {
 
 2312            $constname = 
'MAIN_MODULE_'.$forcename.
"_DIR_";
 
 2314          if (!empty($subname)) {
 
 2315            $constname = $constname.$subname.
"_";
 
 2318          $name = $constname.strtoupper($this->dirs[$key][0]);
 
 2323          $fulldir = DOL_DATA_ROOT.$dir;
 
 2325          $fulldir = DOL_DATA_ROOT.
"/".
$conf->entity.$dir;
 
 2328        if (!empty($fulldir) && !file_exists($fulldir)) {
 
 2329          if (
dol_mkdir($fulldir, DOL_DATA_ROOT) < 0) {
 
 2330            $this->error = $langs->trans(
"ErrorCanNotCreateDir", $fulldir);
 
 2331            dol_syslog(get_class($this).
"::_init ".$this->error, LOG_ERR);
 
 2337        if (!empty($addtodatabase) && !empty($name)) {
 
 
 2366    $sql = 
"SELECT count(*)";
 
 2367    $sql .= 
" FROM ".MAIN_DB_PREFIX.
"const";
 
 2368    $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" = '".$this->db->escape($name).
"'";
 
 2369    $sql .= 
" AND entity = ".$conf->entity;
 
 2371    dol_syslog(get_class($this).
"::insert_dirs", LOG_DEBUG);
 
 2372    $result = $this->db->query($sql);
 
 2374      $row = $this->db->fetch_row($result);
 
 2377        $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"const (name, type, value, note, visible, entity)";
 
 2378        $sql .= 
" VALUES (".$this->db->encrypt($name).
", 'chaine', ".$this->db->encrypt($dir).
", '".$this->db->escape(
"Directory for module ".$this->
name).
"', '0', ".((int) 
$conf->entity).
")";
 
 2380        dol_syslog(get_class($this).
"::insert_dirs", LOG_DEBUG);
 
 2381        $this->db->query($sql);
 
 2384      $this->error = $this->db->lasterror();
 
 
 2405    $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
 
 2406    $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" LIKE '".$this->db->escape($this->const_name).
"_DIR_%'";
 
 2407    $sql .= 
" AND entity = ".$conf->entity;
 
 2409    dol_syslog(get_class($this).
"::delete_dirs", LOG_DEBUG);
 
 2410    if (!$this->db->query($sql)) {
 
 2411      $this->error = $this->db->lasterror();
 
 
 2428    global 
$conf, $langs;
 
 2432    if (is_array($this->module_parts)) {
 
 2433      if (empty($this->module_parts[
'icon']) && !empty($this->picto) && preg_match(
'/^fa\-/', $this->picto)) {
 
 2434        $this->module_parts[
'icon'] = $this->picto;
 
 2437      foreach ($this->module_parts as $key => $value) {
 
 2438        if (is_array($value) && count($value) == 0) {
 
 2443        if ($key == 
'websitetemplates' && $value == 1) {
 
 2447          $docs = 
dol_dir_list($srcroot, 
'directories', 0, 
'website_.*$');
 
 2448          foreach ($docs as $cursorfile) {
 
 2449            $src = $srcroot.
'/'.$cursorfile[
'name'];
 
 2450            $dest = DOL_DATA_ROOT.
'/doctemplates/websites/'.$cursorfile[
'name'];
 
 2457            $result = dol_compress_dir($src, $dest.
'.zip', 
'zip');
 
 2460              $this->error = ($errormsg ? $errormsg : $langs->trans(
'ErrorFailToCreateZip', $dest));
 
 2461              $this->errors[] = ($errormsg ? $errormsg : $langs->trans(
'ErrorFailToCreateZip', $dest));
 
 2466          $docs = 
dol_dir_list($srcroot, 
'files', 0, 
'website_.*\.jpg$');
 
 2467          foreach ($docs as $cursorfile) {
 
 2468            $src = $srcroot.
'/'.$cursorfile[
'name'];
 
 2469            $dest = DOL_DATA_ROOT.
'/doctemplates/websites/'.$cursorfile[
'name'];
 
 2475        $entity = 
$conf->entity; 
 
 2479        if (is_array($value)) {
 
 2482          if (isset($value[
'data']) && is_array($value[
'data'])) {
 
 2483            $newvalue = json_encode($value[
'data']);
 
 2484            if (isset($value[
'entity'])) {
 
 2485              $entity = $value[
'entity'];
 
 2487          } elseif (isset($value[
'data']) && !is_array($value[
'data'])) {
 
 2488            $newvalue = $value[
'data'];
 
 2489            if (isset($value[
'entity'])) {
 
 2490              $entity = $value[
'entity'];
 
 2493            $newvalue = json_encode($value);
 
 2497        if (!empty($newvalue)) {
 
 2498          $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"const (";
 
 2503          $sql .= 
", visible";
 
 2506          $sql .= 
" VALUES (";
 
 2507          $sql .= 
" ".$this->db->encrypt($this->const_name.
"_".strtoupper($key), 1);
 
 2508          $sql .= 
", 'chaine'";
 
 2509          $sql .= 
", ".$this->db->encrypt($newvalue, 1);
 
 2512          $sql .= 
", ".((int) $entity);
 
 2515          dol_syslog(get_class($this).
"::insert_module_parts for key=".$this->const_name.
"_".strtoupper($key), LOG_DEBUG);
 
 2517          $resql = $this->db->query($sql, 1);
 
 2519            if ($this->db->lasterrno() != 
'DB_ERROR_RECORD_ALREADY_EXISTS') {
 
 2521              $this->error = $this->db->lasterror();
 
 2523              dol_syslog(get_class($this).
"::insert_module_parts for ".$this->const_name.
"_".strtoupper($key).
" Record already exists.", LOG_WARNING);
 
 
 2545    if (is_array($this->module_parts)) {
 
 2546      dol_syslog(get_class($this).
"::delete_module_parts", LOG_DEBUG);
 
 2548      if (empty($this->module_parts[
'icon']) && !empty($this->picto) && preg_match(
'/^fa\-/', $this->picto)) {
 
 2549        $this->module_parts[
'icon'] = $this->picto;
 
 2552      foreach ($this->module_parts as $key => $value) {
 
 2554        if (is_array($value) && isset($value[
'entity'])) {
 
 2555          $entity = $value[
'entity'];
 
 2557          $entity = 
$conf->entity;
 
 2560        $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.
"const";
 
 2561        $sql .= 
" WHERE ".$this->db->decrypt(
'name').
" LIKE '".$this->db->escape($this->const_name).
"_".strtoupper($key).
"'";
 
 2562        $sql .= 
" AND entity = ".((int) $entity);
 
 2564        if (!$this->db->query($sql)) {
 
 2565          $this->error = $this->db->lasterror();
 
 
 2582  public function init($options = 
'')
 
 2584    return $this->
_init(array(), $options);
 
 
 2595  public function remove($options = 
'')
 
 2597    return $this->
_remove(array(), $options);
 
 
 2615      $imginfo = 
"info_black";
 
 2618    $const_name = 
'MAIN_MODULE_'.strtoupper(preg_replace(
'/^mod/i', 
'', get_class($this)));
 
 2622    if (preg_match(
'/development/i', $version)) {
 
 2623      $versiontrans .= 
'warning';
 
 2625    if (preg_match(
'/experimental/i', $version)) {
 
 2626      $versiontrans .= 
'warning';
 
 2628    if (preg_match(
'/deprecated/i', $version)) {
 
 2629      $versiontrans .= 
'warning';
 
 2633      <div class="box-flex-item info-box-module' 
 2634      .(getDolGlobalString($const_name) ? 
'' : 
' --disabled')
 
 2636      .($this->needUpdate ? 
' --need-update' : 
'')
 
 2638      <div class="info-box info-box-sm info-box-module"> 
 2639      <div class="info-box-icon'.(!
getDolGlobalString($const_name) ? 
'' : 
' info-box-icon-module-enabled'.($versiontrans ? 
' info-box-icon-module-warning' : 
'')).
'">';
 
 2644    if (!empty($this->picto)) {
 
 2645      if (preg_match(
'/^\//i', $this->picto)) {
 
 2646        $return .= 
img_picto($alttext, $this->picto, 
'class="inline-block valignmiddle"', 1);
 
 2648        $return .= 
img_object($alttext, $this->picto, 
'class="inline-block valignmiddle"');
 
 2651      $return .= 
img_object($alttext, 
'generic', 
'class="inline-block valignmiddle"');
 
 2654    if ($this->
isCoreOrExternalModule() == 
'external' || preg_match(
'/development|experimental|deprecated/i', $version)) {
 
 2655      $versionTitle =  $langs->trans(
"Version").
' '.$this->
getVersion(1);
 
 2656      if ($this->needUpdate) {
 
 2657        $versionTitle .= 
'<br>'.$langs->trans(
'ModuleUpdateAvailable').
' : '.
$this->lastVersion;
 
 2660      $return .=  
'<span class="info-box-icon-version'.($versiontrans ? 
' '.$versiontrans : 
'').
' classfortooltip" title="'.
dol_escape_js($versionTitle).
'" >';
 
 2662      $return .=  
'</span>';
 
 2666      <div class="info-box-content info-box-text-module'.(!
getDolGlobalString($const_name) ? 
'' : 
' info-box-module-enabled'.($versiontrans ? 
' info-box-content-warning' : 
'')).
'"> 
 2667      <span class="info-box-title">'.$this->
getName().
'</span> 
 2670    $return .=  
'<div class="valignmiddle inline-block info-box-more">';
 
 2672    $return .=  
'<a class="valignmiddle inline-block" href="javascript:document_preview(\''.DOL_URL_ROOT.
'/admin/modulehelp.php?id='.((int) $this->numero).
'\',\
'text/html\',\''.dol_escape_js($langs->trans(
"Module")).
'\')
">'.img_picto(($this->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule
").' - ' : '').$langs->trans("ClickToShowDescription
"), $imginfo).'</a>'; 
 2673    $return .=  '</div><br>'; 
 2675    $return .=  '<div class="valignmiddle 
inline-block info-box-actions
">'; 
 2676    $return .=  '<div class="valignmiddle 
inline-block info-box-setup
">'; 
 2677    $return .=  $codetoconfig; 
 2678    $return .=  '</div>'; 
 2679    $return .=  '<div class="valignmiddle 
inline-block marginleftonly marginrightonly
">'; 
 2680    $return .=  $codeenabledisable; 
 2681    $return .=  '</div>'; 
 2682    $return .=  '</div>'; 
 2685      </div><!-- /.info-box-content --> 
 2686      </div><!-- /.info-box --> 
 
 2700  public function checkForUpdate()
 
 2702    require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
 
 2703    if (!empty($this->url_last_version)) {
 
 2704      $lastVersion = getURLContent($this->url_last_version, 'GET', '', 1, array(), array('http', 'https'), 0);  // Accept http or https links on external remote server only
 
 2705      if (isset($lastVersion['content']) && strlen($lastVersion['content']) < 30) {
 
 2706        // 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 _ . -
 
 2707        $this->lastVersion = preg_replace("/[^a-zA-Z0-9_\.\-]+/
", "", $lastVersion['content']); 
 2708        if (version_compare($this->lastVersion, $this->version) > 0) { 
 2709          $this->needUpdate = true; 
 2712          $this->needUpdate = false; 
 
 2729  public function checkForCompliance($nametocheck = '')
 
 2731    global $conf, $langs;
 
 2733    if (empty($nametocheck)) {
 
 2734      $nametocheck = $this->name;
 
 2737    // Get list of illegal modules name or ID
 
 2738    if (empty($conf->cache['noncompliantmodules'])) {
 
 2739      require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
 
 2741      $result = getURLContent(self::URL_FOR_BLACKLISTED_MODULES, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
 
 2742      if (isset($result['content']) && $result['http_code'] == 200) {
 
 2743        $langs->load("errors
"); 
 2745        // 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 _ . - 
 2746        $arrayoflines = preg_split("/[\n,]/
", $result['content']); 
 2747        foreach ($arrayoflines as $line) { 
 2748          $tmpfieldsofline = explode(';', $line); 
 2749          $modulekey = strtolower($tmpfieldsofline[0]); 
 2750          $conf->cache['noncompliantmodules'][$modulekey]['name'] = $tmpfieldsofline[0]; 
 2751          $conf->cache['noncompliantmodules'][$modulekey]['id'] = $tmpfieldsofline[1]; 
 2752          $conf->cache['noncompliantmodules'][$modulekey]['signature'] = $tmpfieldsofline[2]; 
 2753          $conf->cache['noncompliantmodules'][$modulekey]['message'] = $langs->trans(empty($tmpfieldsofline[3]) ? 'WarningModuleAffiliatedToAReportedCompany' : $tmpfieldsofline[3]); 
 2754          if (!empty($tmpfieldsofline[4])) { 
 2755            $message2 = $langs->trans("WarningModuleAffiliatedToAPiratPlatform
", '{s}'); 
 2756            $listofillegalurl = ''; 
 2757            foreach (explode(" ", $tmpfieldsofline[4]) as $illegalurl) { 
 2758              $listofillegalurl .= ($listofillegalurl ? ' '.$langs->trans("or
").' ' : '').'<b>'.preg_replace('/[^a-z0-9\.\-]/', '', $illegalurl).'</b>'; 
 2760            $message2 = str_replace('{s}', $listofillegalurl, $message2); 
 2761            $conf->cache['noncompliantmodules'][$modulekey]['message2'] = $message2; 
 2767    if (!empty($conf->cache['noncompliantmodules'])) { 
 2768      $modulekey = strtolower($nametocheck); 
 2769      if (in_array($modulekey, array_keys($conf->cache['noncompliantmodules']))) { 
 2770        $answer = trim($conf->cache['noncompliantmodules'][$modulekey]['message']); 
 2771        if (!empty($conf->cache['noncompliantmodules'][$modulekey]['message2'])) { 
 2772          $answer .= '<br>'.$conf->cache['noncompliantmodules'][$modulekey]['message2']; 
 
 2799  protected function declareNewDictionary($dictionaryArray, $langs = '')
 
 2801    $fields = array('name', 'lib', 'sql', 'sqlsort', 'field', 'fieldvalue', 'fieldinsert', 'rowid', 'cond', 'help', 'fieldcheck');
 
 2803    foreach ($fields as $field) {
 
 2804      if (isset($dictionaryArray[$field])) {
 
 2805        // @phan-suppress-next-line PhanTypeMismatchProperty
 
 2806        $this->dictionaries['tab'.$field][] = $dictionaryArray[$field];
 
 2809    if ($langs && !in_array($langs, $this->dictionaries[$langs])) {
 
 2810      $this->dictionaries['langs'][] = $langs;
 
 
 
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.
 
delete_permissions()
Removes access rights.
 
getImportDatasetLabel($r)
Gives translated label of an import dataset.
 
_init($array_sql, $options='')
Enables a module.
 
getLastActivationDate()
Gives the last date of activation.
 
$needUpdate
true indicate this module need update
 
delete_cronjobs()
Removes boxes.
 
getKanbanView($codeenabledisable='', $codetoconfig='')
Return Kanban view of a module.
 
getModulePosition()
Gives the module position.
 
insert_const()
Adds constants.
 
__construct($db)
Constructor.
 
delete_boxes()
Removes boxes.
 
isCoreOrExternalModule()
Tells if module is core or external.
 
getDescLongReadmeFound()
Return path of file if a README file was found.
 
insert_permissions($reinitadminperms=0, $force_entity=null, $notrigger=0)
Adds access rights.
 
delete_menus()
Removes menu entries.
 
delete_const()
Removes constants tagged 'deleteonunactive'.
 
_active()
Insert constants for module activation.
 
_remove($array_sql, $options='')
Disable function.
 
getDescLong()
Gives the long description of a module.
 
insert_boxes($option='')
Adds boxes.
 
getPublisher()
Gives the publisher name.
 
getChangeLog()
Gives the changelog.
 
insert_cronjobs()
Adds cronjobs.
 
create_dirs()
Creates directories.
 
delete_module_parts()
Removes generic parts.
 
getVersion($translated=1)
Gives module version (translated if param $translated is on) For 'experimental' modules,...
 
$lastVersion
Module last version.
 
_unactive()
Module deactivation.
 
getDesc()
Gives the translated module description if translation exists in admin.lang or the default module des...
 
delete_tabs()
Removes tabs.
 
getExportDatasetLabel($r)
Gives translated label of an export dataset.
 
getName()
Gives the translated module name if translation exists in admin.lang or into language files of module...
 
_load_tables($reldir, $onlywithsuffix='')
Create tables and keys required by module:
 
insert_dirs($name, $dir)
Adds directories definitions.
 
getLangFilesArray()
Gives module related language files list.
 
insert_menus()
Adds menu entries.
 
insert_module_parts()
Save configuration for generic features.
 
getPublisherUrl()
Gives the publisher url.
 
getLastActivationInfo()
Gives the last author of activation.
 
delete_dirs()
Removes directories.
 
init($options='')
Function called when module is enabled.
 
static getListOfPagesForBoxes()
Name of positions (See below)
 
Class to manage Dolibarr users.
 
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
 
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_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.
 
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
 
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
 
dol_now($mode='auto')
Return date for now.
 
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
 
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...
 
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
 
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)
 
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...
 
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
 
dolMd2Html($content, $parser='parsedown', $replaceimagepath=null)
Function to parse MD content into HTML.
 
$conf db name
Only used if Module[ID]Name translation string is not found.