dolibarr  7.0.0-beta
DolibarrModules.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
4  * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
5  * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
6  * Copyright (C) 2005-2013 Laurent Destailleur <eldy@users.sourceforge.net>
7  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
8  * Copyright (C) 2014 RaphaĆ«l Doursenaud <rdoursenaud@gpcsolutions.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
35 class DolibarrModules // Can not be abstract, because we need to instantiate it into unActivateModule to be able to disable a module whose files were removed.
36 {
40  public $db;
41 
46  public $numero;
47 
52  public $editor_name;
53 
58  public $editor_url;
59 
67  public $family;
68 
82  public $familyinfo;
83 
88  public $module_position=500;
89 
98  public $name;
99 
105  public $dirs = array();
106 
110  public $boxes = array();
111 
115  public $const = array();
116 
120  public $cronjobs = array();
121 
125  public $rights;
126 
130  public $rights_class;
131 
135  public $menu = array();
136 
171  public $module_parts = array();
172 
177  public $docs;
178 
183  public $dbversion = "-";
184 
188  public $error;
189 
201  public $version;
202 
208  public $description;
209 
216  public $descriptionlong;
217 
218 
219  // For exports
220 
224  public $export_code;
225 
229  public $export_label;
230 
231  public $export_permission;
232  public $export_fields_array;
233  public $export_TypeFields_array;
234  public $export_entities_array;
235  public $export_special_array; // special or computed field
236  public $export_dependencies_array;
237  public $export_sql_start;
238  public $export_sql_end;
239  public $export_sql_order;
240 
241 
242  // For import
243 
247  public $import_code;
248 
252  public $import_label;
253 
254 
258  public $const_name;
259 
263  public $always_enabled;
264 
268  public $core_enabled;
269 
275  public $style_sheet = '';
276 
288  public $special;
289 
296  public $picto;
297 
304  public $config_page_url;
305 
306 
312  public $depends;
313 
317  public $requiredby;
318 
323  public $conflictwith;
324 
328  public $langfiles;
329 
335  public $warnings_activation;
336 
342  public $warnings_activation_ext;
343 
344 
349  public $phpmin;
350 
355  public $need_dolibarr_version;
356 
360  public $hidden = false;
361 
362 
363 
364 
365 
371  public function __construct($db)
372  {
373  $this->db = $db;
374  }
375  // We should but can't set this as abstract because this will make dolibarr hang
376  // after migration due to old module not implementing. We must wait PHP is able to make
377  // a try catch on Fatal error to manage this correctly.
378  // We need constructor into function unActivateModule into admin.lib.php
379 
380 
392  function _init($array_sql, $options='')
393  {
394  global $conf;
395  $err=0;
396 
397  $this->db->begin();
398 
399  // Insert activation module constant
400  if (! $err) $err+=$this->_active();
401 
402  // Insert new pages for tabs (into llx_const)
403  if (! $err) $err+=$this->insert_tabs();
404 
405  // Insert activation of module's parts
406  if (! $err) $err+=$this->insert_module_parts();
407 
408  // Insert constant defined by modules (into llx_const)
409  if (! $err && ! preg_match('/newboxdefonly/',$options)) $err+=$this->insert_const(); // Test on newboxdefonly to avoid to erase value during upgrade
410 
411  // Insert boxes def into llx_boxes_def and boxes setup (into llx_boxes)
412  if (! $err && ! preg_match('/noboxes/',$options)) $err+=$this->insert_boxes($options);
413 
414  // Insert cron job entries (entry in llx_cronjobs)
415  if (! $err) $err+=$this->insert_cronjobs();
416 
417  // Insert permission definitions of module into llx_rights_def. If user is admin, grant this permission to user.
418  if (! $err) $err+=$this->insert_permissions(1, null, 1);
419 
420  // Insert specific menus entries into database
421  if (! $err) $err+=$this->insert_menus();
422 
423  // Create module's directories
424  if (! $err) $err+=$this->create_dirs();
425 
426  // Execute addons requests
427  $num=count($array_sql);
428  for ($i = 0; $i < $num; $i++)
429  {
430  if (! $err)
431  {
432  $val=$array_sql[$i];
433  $sql=$val;
434  $ignoreerror=0;
435  if (is_array($val))
436  {
437  $sql=$val['sql'];
438  $ignoreerror=$val['ignoreerror'];
439  }
440  // Add current entity id
441  $sql=str_replace('__ENTITY__', $conf->entity, $sql);
442 
443  dol_syslog(get_class($this)."::_init ignoreerror=".$ignoreerror."", LOG_DEBUG);
444  $result=$this->db->query($sql, $ignoreerror);
445  if (! $result)
446  {
447  if (! $ignoreerror)
448  {
449  $this->error=$this->db->lasterror();
450  $err++;
451  }
452  else
453  {
454  dol_syslog(get_class($this)."::_init Warning ".$this->db->lasterror(), LOG_WARNING);
455  }
456  }
457  }
458  }
459 
460  // Return code
461  if (! $err)
462  {
463  $this->db->commit();
464  return 1;
465  }
466  else
467  {
468  $this->db->rollback();
469  return 0;
470  }
471  }
472 
482  function _remove($array_sql, $options='')
483  {
484  $err=0;
485 
486  $this->db->begin();
487 
488  // Remove activation module line (constant MAIN_MODULE_MYMODULE in llx_const)
489  if (! $err) $err+=$this->_unactive();
490 
491  // Remove activation of module's new tabs (MAIN_MODULE_MYMODULE_TABS_XXX in llx_const)
492  if (! $err) $err+=$this->delete_tabs();
493 
494  // Remove activation of module's parts (MAIN_MODULE_MYMODULE_XXX in llx_const)
495  if (! $err) $err+=$this->delete_module_parts();
496 
497  // Remove constants defined by modules
498  if (! $err) $err+=$this->delete_const();
499 
500  // Remove list of module's available boxes (entry in llx_boxes)
501  if (! $err && ! preg_match('/(newboxdefonly|noboxes)/',$options)) $err+=$this->delete_boxes(); // We don't have to delete if option ask to keep boxes safe or ask to add new box def only
502 
503  // Remove list of module's cron job entries (entry in llx_cronjobs)
504  if (! $err) $err+=$this->delete_cronjobs();
505 
506  // Remove module's permissions from list of available permissions (entries in llx_rights_def)
507  if (! $err) $err+=$this->delete_permissions();
508 
509  // Remove module's menus (entries in llx_menu)
510  if (! $err) $err+=$this->delete_menus();
511 
512  // Remove module's directories
513  if (! $err) $err+=$this->delete_dirs();
514 
515  // Run complementary sql requests
516  $num=count($array_sql);
517  for ($i = 0; $i < $num; $i++)
518  {
519  if (! $err)
520  {
521  dol_syslog(get_class($this)."::_remove", LOG_DEBUG);
522  $result=$this->db->query($array_sql[$i]);
523  if (! $result)
524  {
525  $this->error=$this->db->error();
526  $err++;
527  }
528  }
529  }
530 
531  // Return code
532  if (! $err)
533  {
534  $this->db->commit();
535  return 1;
536  }
537  else
538  {
539  $this->db->rollback();
540  return 0;
541  }
542  }
543 
544 
551  function getName()
552  {
553  global $langs;
554  $langs->load("admin");
555 
556  if ($langs->transnoentitiesnoconv("Module".$this->numero."Name") != ("Module".$this->numero."Name"))
557  {
558  // If module name translation exists
559  return $langs->transnoentitiesnoconv("Module".$this->numero."Name");
560  }
561  else
562  {
563  // If module name translation using it's unique id does not exists, we try to use its name to find translation
564  if (is_array($this->langfiles))
565  {
566  foreach($this->langfiles as $val)
567  {
568  if ($val) $langs->load($val);
569  }
570  }
571 
572  if ($langs->trans("Module".$this->name."Name") != ("Module".$this->name."Name"))
573  {
574  // If module name translation exists
575  return $langs->transnoentitiesnoconv("Module".$this->name."Name");
576  }
577 
578  // Last chance with simple label
579  return $langs->transnoentitiesnoconv($this->name);
580  }
581  }
582 
583 
589  function getDesc()
590  {
591  global $langs;
592  $langs->load("admin");
593 
594  if ($langs->transnoentitiesnoconv("Module".$this->numero."Desc") != ("Module".$this->numero."Desc"))
595  {
596  // If module description translation exists
597  return $langs->transnoentitiesnoconv("Module".$this->numero."Desc");
598  }
599  else
600  {
601  // If module description translation does not exist using its unique id, we can use its name to find translation
602  if (is_array($this->langfiles))
603  {
604  foreach($this->langfiles as $val)
605  {
606  if ($val) $langs->load($val);
607  }
608  }
609 
610  if ($langs->transnoentitiesnoconv("Module".$this->name."Desc") != ("Module".$this->name."Desc"))
611  {
612  // If module name translation exists
613  return $langs->trans("Module".$this->name."Desc");
614  }
615 
616  // Last chance with simple label
617  return $langs->trans($this->description);
618  }
619  }
620 
627  function getDescLong()
628  {
629  global $langs;
630  $langs->load("admin");
631 
632  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
633  include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
634 
635  $pathoffile = $this->getDescLongReadmeFound();
636 
637  if ($pathoffile) // Mostly for external modules
638  {
639  $content = file_get_contents($pathoffile);
640 
641  if ((float) DOL_VERSION >= 6.0)
642  {
643  @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php';
644 
645  $content = dolMd2Html($content, 'parsedown',
646  array(
647  'doc/'=>dol_buildpath(strtolower($this->name).'/doc/', 1),
648  'img/'=>dol_buildpath(strtolower($this->name).'/img/', 1),
649  'images/'=>dol_buildpath(strtolower($this->name).'/imgages/', 1),
650  ));
651  }
652  else
653  {
654  $content = nl2br($content);
655  }
656  }
657  else // Mostly for internal modules
658  {
659  if (! empty($this->descriptionlong))
660  {
661  if (is_array($this->langfiles))
662  {
663  foreach($this->langfiles as $val)
664  {
665  if ($val) $langs->load($val);
666  }
667  }
668 
669  $content = $langs->transnoentitiesnoconv($this->descriptionlong);
670  }
671  }
672 
673  return $content;
674  }
675 
682  {
683  global $langs;
684 
685  $filefound= false;
686 
687  // Define path to file README.md.
688  // First check README-la_LA.md then README-la.md then README.md
689  $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0);
690  if (dol_is_file($pathoffile))
691  {
692  $filefound = true;
693  }
694  if (! $filefound)
695  {
696  $tmp=explode('_', $langs->defaultlang);
697  $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$tmp[0].'.md', 0);
698  if (dol_is_file($pathoffile))
699  {
700  $filefound = true;
701  }
702  }
703  if (! $filefound)
704  {
705  $pathoffile = dol_buildpath(strtolower($this->name).'/README.md', 0);
706  if (dol_is_file($pathoffile))
707  {
708  $filefound = true;
709  }
710  }
711 
712  return ($filefound?$pathoffile:'');
713  }
714 
715 
721  function getChangeLog()
722  {
723  global $langs;
724  $langs->load("admin");
725 
726  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
727  include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
728 
729  $filefound= false;
730 
731  // Define path to file README.md.
732  // First check README-la_LA.md then README.md
733  $pathoffile = dol_buildpath(strtolower($this->name).'/ChangeLog-'.$langs->defaultlang.'.md', 0);
734  if (dol_is_file($pathoffile))
735  {
736  $filefound = true;
737  }
738  if (! $filefound)
739  {
740  $pathoffile = dol_buildpath(strtolower($this->name).'/ChangeLog.md', 0);
741  if (dol_is_file($pathoffile))
742  {
743  $filefound = true;
744  }
745  }
746 
747  if ($filefound) // Mostly for external modules
748  {
749  $content = file_get_contents($pathoffile);
750 
751  if ((float) DOL_VERSION >= 6.0)
752  {
753  @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php';
754  $content = dolMd2Html($content, 'parsedown', array('doc/'=>dol_buildpath(strtolower($this->name).'/doc/', 1)));
755  }
756  else
757  {
758  $content = nl2br($content);
759  }
760  }
761 
762  return $content;
763  }
764 
770  function getPublisher()
771  {
772  return $this->editor_name;
773  }
774 
780  function getPublisherUrl()
781  {
782  return $this->editor_url;
783  }
784 
793  function getVersion($translated=1)
794  {
795  global $langs;
796  $langs->load("admin");
797 
798  $ret='';
799 
800  $newversion=preg_replace('/_deprecated/','',$this->version);
801  if ($newversion == 'experimental') $ret=($translated?$langs->transnoentitiesnoconv("VersionExperimental"):$newversion);
802  elseif ($newversion == 'development') $ret=($translated?$langs->transnoentitiesnoconv("VersionDevelopment"):$newversion);
803  elseif ($newversion == 'dolibarr') $ret=DOL_VERSION;
804  elseif ($newversion) $ret=$newversion;
805  else $ret=($translated?$langs->transnoentitiesnoconv("VersionUnknown"):'unknown');
806 
807  if (preg_match('/_deprecated/',$this->version)) $ret.=($translated?' ('.$langs->transnoentitiesnoconv("Deprecated").')':$this->version);
808  return $ret;
809  }
810 
811 
818  {
819  if ($this->version == 'dolibarr' || $this->version == 'dolibarr_deprecated') return 'core';
820  if (! empty($this->version) && ! in_array($this->version,array('experimental','development'))) return 'external';
821  if (! empty($this->editor_name) || ! empty($this->editor_url)) return 'external';
822  if ($this->numero >= 100000) return 'external';
823  return 'unknown';
824  }
825 
826 
832  function getLangFilesArray()
833  {
834  return $this->langfiles;
835  }
836 
845  {
846  global $langs;
847 
848  $langstring="ExportDataset_".$this->export_code[$r];
849  if ($langs->trans($langstring) == $langstring)
850  {
851  // Translation not found
852  return $langs->trans($this->export_label[$r]);
853  }
854  else
855  {
856  // Translation found
857  return $langs->trans($langstring);
858  }
859  }
860 
861 
870  {
871  global $langs;
872 
873  $langstring="ImportDataset_".$this->import_code[$r];
874  //print "x".$langstring;
875  if ($langs->trans($langstring) == $langstring)
876  {
877  // Translation not found
878  return $langs->transnoentitiesnoconv($this->import_label[$r]);
879  }
880  else
881  {
882  // Translation found
883  return $langs->transnoentitiesnoconv($langstring);
884  }
885  }
886 
887 
894  {
895  global $conf;
896 
897  $sql = "SELECT tms FROM ".MAIN_DB_PREFIX."const";
898  $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'";
899  $sql.= " AND entity IN (0, ".$conf->entity.")";
900 
901  dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG);
902  $resql=$this->db->query($sql);
903  if (! $resql) $err++;
904  else
905  {
906  $obj=$this->db->fetch_object($resql);
907  if ($obj) return $this->db->jdate($obj->tms);
908  }
909 
910  return '';
911  }
912 
913 
920  {
921  global $conf;
922 
923  $sql = "SELECT tms, note FROM ".MAIN_DB_PREFIX."const";
924  $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'";
925  $sql.= " AND entity IN (0, ".$conf->entity.")";
926 
927  dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG);
928  $resql=$this->db->query($sql);
929  if (! $resql) $err++;
930  else
931  {
932  $obj=$this->db->fetch_object($resql);
933  $tmp=array();
934  if ($obj->note)
935  {
936  $tmp=json_decode($obj->note, true);
937  }
938  if ($obj) return array('authorid'=>$tmp['authorid'], 'ip'=>$tmp['ip'], 'lastactivationdate'=>$this->db->jdate($obj->tms));
939  }
940 
941  return array();
942  }
943 
944 
950  function _active()
951  {
952  global $conf, $user;
953 
954  $err = 0;
955 
956  // Common module
957  $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity);
958 
959  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
960  $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'";
961  $sql.= " AND entity IN (0, ".$entity.")";
962 
963  dol_syslog(get_class($this)."::_active", LOG_DEBUG);
964  $resql=$this->db->query($sql);
965  if (! $resql) $err++;
966 
967  $note=json_encode(array('authorid'=>(is_object($user)?$user->id:0), 'ip'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR'])));
968 
969  $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name, value, visible, entity, note) VALUES";
970  $sql.= " (".$this->db->encrypt($this->const_name,1);
971  $sql.= ", ".$this->db->encrypt('1',1);
972  $sql.= ", 0, ".$entity;
973  $sql.= ", '".$this->db->escape($note)."')";
974 
975  dol_syslog(get_class($this)."::_active", LOG_DEBUG);
976  $resql=$this->db->query($sql);
977  if (! $resql) $err++;
978 
979  return $err;
980  }
981 
982 
988  function _unactive()
989  {
990  global $conf;
991 
992  $err = 0;
993 
994  // Common module
995  $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity);
996 
997  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
998  $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'";
999  $sql.= " AND entity IN (0, ".$entity.")";
1000 
1001  dol_syslog(get_class($this)."::_unactive", LOG_DEBUG);
1002  $this->db->query($sql);
1003 
1004  return $err;
1005  }
1006 
1007 
1017  function _load_tables($reldir)
1018  {
1019  global $conf;
1020 
1021  $error=0;
1022  $dirfound=0;
1023 
1024  if (empty($reldir)) return 1;
1025 
1026  include_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
1027 
1028  $ok = 1;
1029  foreach($conf->file->dol_document_root as $dirroot)
1030  {
1031  if ($ok)
1032  {
1033  $dir = $dirroot.$reldir;
1034  $ok = 0;
1035 
1036  $handle=@opendir($dir); // Dir may not exists
1037  if (is_resource($handle))
1038  {
1039  $dirfound++;
1040 
1041  // Run llx_mytable.sql files, then llx_mytable_*.sql
1042  $files = array();
1043  while (($file = readdir($handle))!==false)
1044  {
1045  $files[] = $file;
1046  }
1047  sort($files);
1048  foreach ($files as $file)
1049  {
1050  if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data')
1051  {
1052  $result=run_sql($dir.$file,1,'',1);
1053  if ($result <= 0) $error++;
1054  }
1055  }
1056 
1057  rewinddir($handle);
1058 
1059  // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) then then llx_mytable_*.key.sql
1060  $files = array();
1061  while (($file = readdir($handle))!==false)
1062  {
1063  $files[] = $file;
1064  }
1065  sort($files);
1066  foreach ($files as $file)
1067  {
1068  if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data')
1069  {
1070  $result=run_sql($dir.$file,1,'',1);
1071  if ($result <= 0) $error++;
1072  }
1073  }
1074 
1075  rewinddir($handle);
1076 
1077  // Run data_xxx.sql files (Must be done after llx_mytable.key.sql)
1078  $files = array();
1079  while (($file = readdir($handle))!==false)
1080  {
1081  $files[] = $file;
1082  }
1083  sort($files);
1084  foreach ($files as $file)
1085  {
1086  if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data')
1087  {
1088  $result=run_sql($dir.$file,1,'',1);
1089  if ($result <= 0) $error++;
1090  }
1091  }
1092 
1093  rewinddir($handle);
1094 
1095  // Run update_xxx.sql files
1096  $files = array();
1097  while (($file = readdir($handle))!==false)
1098  {
1099  $files[] = $file;
1100  }
1101  sort($files);
1102  foreach ($files as $file)
1103  {
1104  if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update')
1105  {
1106  $result=run_sql($dir.$file,1,'',1);
1107  if ($result <= 0) $error++;
1108  }
1109  }
1110 
1111  closedir($handle);
1112  }
1113 
1114  if ($error == 0)
1115  {
1116  $ok = 1;
1117  }
1118  }
1119  }
1120 
1121  if (! $dirfound) dol_syslog("A module ask to load sql files into ".$reldir." but this directory was not found.", LOG_WARNING);
1122  return $ok;
1123  }
1124 
1125 
1133  function insert_boxes($option='')
1134  {
1135  require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php';
1136 
1137  global $conf;
1138 
1139  $err=0;
1140 
1141  if (is_array($this->boxes))
1142  {
1143  $pos_name = InfoBox::getListOfPagesForBoxes();
1144 
1145  foreach ($this->boxes as $key => $value)
1146  {
1147  $file = isset($this->boxes[$key]['file'])?$this->boxes[$key]['file']:'';
1148  $note = isset($this->boxes[$key]['note'])?$this->boxes[$key]['note']:'';
1149  $enabledbydefaulton = isset($this->boxes[$key]['enabledbydefaulton'])?$this->boxes[$key]['enabledbydefaulton']:'Home';
1150 
1151  if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility
1152  if (empty($note)) $note = isset($this->boxes[$key][2])?$this->boxes[$key][2]:''; // For backward compatibility
1153 
1154  // Search if boxes def already present
1155  $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."boxes_def";
1156  $sql.= " WHERE file = '".$this->db->escape($file)."'";
1157  $sql.= " AND entity = ".$conf->entity;
1158  if ($note) $sql.=" AND note ='".$this->db->escape($note)."'";
1159 
1160  dol_syslog(get_class($this)."::insert_boxes", LOG_DEBUG);
1161  $result=$this->db->query($sql);
1162  if ($result)
1163  {
1164  $obj = $this->db->fetch_object($result);
1165  if ($obj->nb == 0)
1166  {
1167  $this->db->begin();
1168 
1169  if (! $err)
1170  {
1171  $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes_def (file, entity, note)";
1172  $sql.= " VALUES ('".$this->db->escape($file)."', ";
1173  $sql.= $conf->entity.", ";
1174  $sql.= $note?"'".$this->db->escape($note)."'":"null";
1175  $sql.= ")";
1176 
1177  dol_syslog(get_class($this)."::insert_boxes", LOG_DEBUG);
1178  $resql=$this->db->query($sql);
1179  if (! $resql) $err++;
1180 
1181  }
1182  if (! $err && ! preg_match('/newboxdefonly/',$option))
1183  {
1184  $lastid=$this->db->last_insert_id(MAIN_DB_PREFIX."boxes_def","rowid");
1185 
1186  foreach ($pos_name as $key2 => $val2)
1187  {
1188  //print 'key2='.$key2.'-val2='.$val2."<br>\n";
1189  if ($enabledbydefaulton && $val2 != $enabledbydefaulton) continue; // Not enabled by default onto this page.
1190 
1191  $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes (box_id,position,box_order,fk_user,entity)";
1192  $sql.= " VALUES (".$lastid.", ".$key2.", '0', 0, ".$conf->entity.")";
1193 
1194  dol_syslog(get_class($this)."::insert_boxes onto page ".$key2."=".$val2."", LOG_DEBUG);
1195  $resql=$this->db->query($sql);
1196  if (! $resql) $err++;
1197  }
1198  }
1199 
1200  if (! $err)
1201  {
1202  $this->db->commit();
1203  }
1204  else
1205  {
1206  $this->error=$this->db->lasterror();
1207  $this->db->rollback();
1208  }
1209  }
1210  // else box already registered into database
1211  }
1212  else
1213  {
1214  $this->error=$this->db->lasterror();
1215  $err++;
1216  }
1217  }
1218  }
1219 
1220  return $err;
1221  }
1222 
1223 
1229  function delete_boxes()
1230  {
1231  global $conf;
1232 
1233  $err=0;
1234 
1235  if (is_array($this->boxes))
1236  {
1237  foreach ($this->boxes as $key => $value)
1238  {
1239  //$titre = $this->boxes[$key][0];
1240  $file = $this->boxes[$key]['file'];
1241  //$note = $this->boxes[$key][2];
1242 
1243  // TODO If the box is also included by another module and the other module is still on, we should not remove it.
1244  // For the moment, we manage this with hard coded exception
1245  //print "Remove box ".$file.'<br>';
1246  if ($file == 'box_graph_product_distribution.php')
1247  {
1248  if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled))
1249  {
1250  dol_syslog("We discard disabling of module ".$file." because another module still active require it.");
1251  continue;
1252  }
1253  }
1254 
1255  if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility
1256 
1257  if ($this->db->type == 'sqlite3') {
1258  // sqlite doesn't support "USING" syntax.
1259  // TODO: remove this dependency.
1260  $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes ";
1261  $sql .= "WHERE ".MAIN_DB_PREFIX."boxes.box_id IN (";
1262  $sql .= "SELECT ".MAIN_DB_PREFIX."boxes_def.rowid ";
1263  $sql .= "FROM ".MAIN_DB_PREFIX."boxes_def ";
1264  $sql .= "WHERE ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."') ";
1265  $sql .= "AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity;
1266  } else {
1267  $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes";
1268  $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def";
1269  $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid";
1270  $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'";
1271  $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity;
1272  }
1273 
1274  dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG);
1275  $resql=$this->db->query($sql);
1276  if (! $resql)
1277  {
1278  $this->error=$this->db->lasterror();
1279  $err++;
1280  }
1281 
1282  $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes_def";
1283  $sql.= " WHERE file = '".$this->db->escape($file)."'";
1284  $sql.= " AND entity = ".$conf->entity;
1285 
1286  dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG);
1287  $resql=$this->db->query($sql);
1288  if (! $resql)
1289  {
1290  $this->error=$this->db->lasterror();
1291  $err++;
1292  }
1293  }
1294  }
1295 
1296  return $err;
1297  }
1298 
1304  function insert_cronjobs()
1305  {
1306  require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php';
1307 
1308  global $conf;
1309 
1310  $err=0;
1311 
1312  if (is_array($this->cronjobs))
1313  {
1314  foreach ($this->cronjobs as $key => $value)
1315  {
1316  $label = isset($this->cronjobs[$key]['label'])?$this->cronjobs[$key]['label']:'';
1317  $jobtype = isset($this->cronjobs[$key]['jobtype'])?$this->cronjobs[$key]['jobtype']:'';
1318  $class = isset($this->cronjobs[$key]['class'])?$this->cronjobs[$key]['class']:'';
1319  $objectname = isset($this->cronjobs[$key]['objectname'])?$this->cronjobs[$key]['objectname']:'';
1320  $method = isset($this->cronjobs[$key]['method'])?$this->cronjobs[$key]['method']:'';
1321  $command = isset($this->cronjobs[$key]['command'])?$this->cronjobs[$key]['command']:'';
1322  $parameters = isset($this->cronjobs[$key]['parameters'])?$this->cronjobs[$key]['parameters']:'';
1323  $comment = isset($this->cronjobs[$key]['comment'])?$this->cronjobs[$key]['comment']:'';
1324  $frequency = isset($this->cronjobs[$key]['frequency'])?$this->cronjobs[$key]['frequency']:'';
1325  $unitfrequency = isset($this->cronjobs[$key]['unitfrequency'])?$this->cronjobs[$key]['unitfrequency']:'';
1326  $status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:'';
1327  $priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:'';
1328  $test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:''; // Line must be visible
1329 
1330  // Search if boxes def already present
1331  $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob";
1332  $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'";
1333  if ($class) $sql.= " AND classesname = '".$this->db->escape($class)."'";
1334  if ($objectname) $sql.= " AND objectname = '".$this->db->escape($objectname)."'";
1335  if ($method) $sql.= " AND methodename = '".$this->db->escape($method)."'";
1336  if ($command) $sql.= " AND command = '".$this->db->escape($command)."'";
1337  $sql.= " AND entity = ".$conf->entity;
1338 
1339  $now=dol_now();
1340 
1341  dol_syslog(get_class($this)."::insert_cronjobs", LOG_DEBUG);
1342  $result=$this->db->query($sql);
1343  if ($result)
1344  {
1345  $obj = $this->db->fetch_object($result);
1346  if ($obj->nb == 0)
1347  {
1348  $this->db->begin();
1349 
1350  if (! $err)
1351  {
1352  $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note,";
1353  if(is_int($frequency)){ $sql.= ' frequency,'; }
1354  if(is_int($unitfrequency)){ $sql.= ' unitfrequency,'; }
1355  if(is_int($priority)){ $sql.= ' priority,'; }
1356  if(is_int($status)){ $sql.= ' status,'; }
1357  $sql.= " entity, test)";
1358  $sql.= " VALUES (";
1359  $sql.= "'".$this->db->escape($this->rights_class)."', ";
1360  $sql.= "'".$this->db->idate($now)."', ";
1361  $sql.= "'".$this->db->idate($now)."', ";
1362  $sql.= "'".$this->db->escape($label)."', ";
1363  $sql.= "'".$this->db->escape($jobtype)."', ";
1364  $sql.= ($class?"'".$this->db->escape($class)."'":"null").",";
1365  $sql.= ($objectname?"'".$this->db->escape($objectname)."'":"null").",";
1366  $sql.= ($method?"'".$this->db->escape($method)."'":"null").",";
1367  $sql.= ($command?"'".$this->db->escape($command)."'":"null").",";
1368  $sql.= ($parameters?"'".$this->db->escape($parameters)."'":"null").",";
1369  $sql.= ($comment?"'".$this->db->escape($comment)."'":"null").",";
1370  if(is_int($frequency)){ $sql.= "'".$this->db->escape($frequency)."', "; }
1371  if(is_int($unitfrequency)){ $sql.= "'".$this->db->escape($unitfrequency)."', "; }
1372  if(is_int($priority)) {$sql.= "'".$this->db->escape($priority)."', ";}
1373  if(is_int($status)){ $sql.= "'".$this->db->escape($status)."', "; }
1374  $sql.= $conf->entity.",";
1375  $sql.= "'".$this->db->escape($test)."'";
1376  $sql.= ")";
1377 
1378  dol_syslog(get_class($this)."::insert_cronjobs", LOG_DEBUG);
1379  $resql=$this->db->query($sql);
1380  if (! $resql) $err++;
1381 
1382  }
1383 
1384  if (! $err)
1385  {
1386  $this->db->commit();
1387  }
1388  else
1389  {
1390  $this->error=$this->db->lasterror();
1391  $this->db->rollback();
1392  }
1393  }
1394  // else box already registered into database
1395  }
1396  else
1397  {
1398  $this->error=$this->db->lasterror();
1399  $err++;
1400  }
1401  }
1402  }
1403 
1404  return $err;
1405  }
1406 
1407 
1413  function delete_cronjobs()
1414  {
1415  global $conf;
1416 
1417  $err=0;
1418 
1419  if (is_array($this->cronjobs))
1420  {
1421  $sql = "DELETE FROM ".MAIN_DB_PREFIX."cronjob";
1422  $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'";
1423  $sql.= " AND entity = ".$conf->entity;
1424 
1425  dol_syslog(get_class($this)."::delete_cronjobs", LOG_DEBUG);
1426  $resql=$this->db->query($sql);
1427  if (! $resql)
1428  {
1429  $this->error=$this->db->lasterror();
1430  $err++;
1431  }
1432  }
1433 
1434  return $err;
1435  }
1436 
1442  function delete_tabs()
1443  {
1444  global $conf;
1445 
1446  $err=0;
1447 
1448  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
1449  $sql.= " WHERE ".$this->db->decrypt('name')." like '".$this->db->escape($this->const_name)."_TABS_%'";
1450  $sql.= " AND entity = ".$conf->entity;
1451 
1452  dol_syslog(get_class($this)."::delete_tabs", LOG_DEBUG);
1453  if (! $this->db->query($sql))
1454  {
1455  $this->error=$this->db->lasterror();
1456  $err++;
1457  }
1458 
1459  return $err;
1460  }
1461 
1467  function insert_tabs()
1468  {
1469  global $conf;
1470 
1471  $err=0;
1472 
1473  if (! empty($this->tabs))
1474  {
1475  $i=0;
1476  foreach ($this->tabs as $key => $value)
1477  {
1478  if (is_array($value) && count($value) == 0) continue; // Discard empty arrays
1479 
1480  $entity=$conf->entity;
1481  $newvalue = $value;
1482 
1483  if (is_array($value))
1484  {
1485  $newvalue = $value['data'];
1486  if (isset($value['entity'])) $entity = $value['entity'];
1487  }
1488 
1489  if ($newvalue)
1490  {
1491  $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
1492  $sql.= "name";
1493  $sql.= ", type";
1494  $sql.= ", value";
1495  $sql.= ", note";
1496  $sql.= ", visible";
1497  $sql.= ", entity";
1498  $sql.= ")";
1499  $sql.= " VALUES (";
1500  $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1);
1501  $sql.= ", 'chaine'";
1502  $sql.= ", ".$this->db->encrypt($newvalue,1);
1503  $sql.= ", null";
1504  $sql.= ", '0'";
1505  $sql.= ", ".$entity;
1506  $sql.= ")";
1507 
1508  dol_syslog(get_class($this)."::insert_tabs", LOG_DEBUG);
1509  $resql = $this->db->query($sql);
1510  if (! $resql)
1511  {
1512  dol_syslog($this->db->lasterror(), LOG_ERR);
1513  if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS')
1514  {
1515  $this->error = $this->db->lasterror();
1516  $this->errors[] = $this->db->lasterror();
1517  $err++;
1518  break;
1519  }
1520  }
1521  }
1522  $i++;
1523  }
1524  }
1525  return $err;
1526  }
1527 
1533  function insert_const()
1534  {
1535  global $conf;
1536 
1537  $err=0;
1538 
1539  if (empty($this->const)) return 0;
1540 
1541  foreach ($this->const as $key => $value)
1542  {
1543  $name = $this->const[$key][0];
1544  $type = $this->const[$key][1];
1545  $val = $this->const[$key][2];
1546  $note = isset($this->const[$key][3])?$this->const[$key][3]:'';
1547  $visible = isset($this->const[$key][4])?$this->const[$key][4]:0;
1548  $entity = (! empty($this->const[$key][5]) && $this->const[$key][5]!='current')?0:$conf->entity;
1549 
1550  // Clean
1551  if (empty($visible)) $visible='0';
1552  if (empty($val) && $val != '0') $val='';
1553 
1554  $sql = "SELECT count(*)";
1555  $sql.= " FROM ".MAIN_DB_PREFIX."const";
1556  $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($name)."'";
1557  $sql.= " AND entity = ".$entity;
1558 
1559  $result=$this->db->query($sql);
1560  if ($result)
1561  {
1562  $row = $this->db->fetch_row($result);
1563 
1564  if ($row[0] == 0) // If not found
1565  {
1566  $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)";
1567  $sql.= " VALUES (";
1568  $sql.= $this->db->encrypt($name,1);
1569  $sql.= ",'".$type."'";
1570  $sql.= ",".(($val != '')?$this->db->encrypt($val,1):"''");
1571  $sql.= ",".($note?"'".$this->db->escape($note)."'":"null");
1572  $sql.= ",'".$visible."'";
1573  $sql.= ",".$entity;
1574  $sql.= ")";
1575 
1576 
1577  dol_syslog(get_class($this)."::insert_const", LOG_DEBUG);
1578  if (! $this->db->query($sql) )
1579  {
1580  $err++;
1581  }
1582  }
1583  else
1584  {
1585  dol_syslog(get_class($this)."::insert_const constant '".$name."' already exists", LOG_WARNING);
1586  }
1587  }
1588  else
1589  {
1590  $err++;
1591  }
1592  }
1593 
1594  return $err;
1595  }
1596 
1602  function delete_const()
1603  {
1604  global $conf;
1605 
1606  $err=0;
1607 
1608  if (empty($this->const)) return 0;
1609 
1610  foreach ($this->const as $key => $value)
1611  {
1612  $name = $this->const[$key][0];
1613  $deleteonunactive = (! empty($this->const[$key][6]))?1:0;
1614 
1615  if ($deleteonunactive)
1616  {
1617  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
1618  $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'";
1619  $sql.= " AND entity in (0, ".$conf->entity.")";
1620  dol_syslog(get_class($this)."::delete_const", LOG_DEBUG);
1621  if (! $this->db->query($sql))
1622  {
1623  $this->error=$this->db->lasterror();
1624  $err++;
1625  }
1626  }
1627  }
1628 
1629  return $err;
1630  }
1631 
1640  function insert_permissions($reinitadminperms=0, $force_entity=null, $notrigger=0)
1641  {
1642  global $conf,$user;
1643 
1644  $err=0;
1645  $entity=(! empty($force_entity) ? $force_entity : $conf->entity);
1646 
1647  // Test if module is activated
1648  $sql_del = "SELECT ".$this->db->decrypt('value')." as value";
1649  $sql_del.= " FROM ".MAIN_DB_PREFIX."const";
1650  $sql_del.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'";
1651  $sql_del.= " AND entity IN (0,".$entity.")";
1652 
1653  dol_syslog(get_class($this)."::insert_permissions", LOG_DEBUG);
1654  $resql=$this->db->query($sql_del);
1655 
1656  if ($resql)
1657  {
1658  $obj=$this->db->fetch_object($resql);
1659  if ($obj !== null && ! empty($obj->value) && ! empty($this->rights))
1660  {
1661  // If the module is active
1662  foreach ($this->rights as $key => $value)
1663  {
1664  $r_id = $this->rights[$key][0];
1665  $r_desc = $this->rights[$key][1];
1666  $r_type = isset($this->rights[$key][2])?$this->rights[$key][2]:'';
1667  $r_def = $this->rights[$key][3];
1668  $r_perms = $this->rights[$key][4];
1669  $r_subperms = isset($this->rights[$key][5])?$this->rights[$key][5]:'';
1670  $r_modul = empty($this->rights_class)?strtolower($this->name):$this->rights_class;
1671 
1672  if (empty($r_type)) $r_type='w';
1673 
1674  // Search if perm already present
1675  $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."rights_def";
1676  $sql.= " WHERE id = ".$r_id." AND entity = ".$entity;
1677  $resqlselect=$this->db->query($sql);
1678 
1679  $obj = $this->db->fetch_object($resqlselect);
1680  if ($obj->nb == 0)
1681  {
1682  if (dol_strlen($r_perms) )
1683  {
1684  if (dol_strlen($r_subperms) )
1685  {
1686  $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def";
1687  $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)";
1688  $sql.= " VALUES ";
1689  $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')";
1690  }
1691  else
1692  {
1693  $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def";
1694  $sql.= " (id, entity, libelle, module, type, bydefault, perms)";
1695  $sql.= " VALUES ";
1696  $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')";
1697  }
1698  }
1699  else
1700  {
1701  $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def ";
1702  $sql .= " (id, entity, libelle, module, type, bydefault)";
1703  $sql .= " VALUES ";
1704  $sql .= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")";
1705  }
1706 
1707  $resqlinsert=$this->db->query($sql,1);
1708 
1709  if (! $resqlinsert)
1710  {
1711  if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS")
1712  {
1713  $this->error=$this->db->lasterror();
1714  $err++;
1715  break;
1716  }
1717  else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO);
1718 
1719  }
1720 
1721  $this->db->free($resqlinsert);
1722  }
1723 
1724  $this->db->free($resqlselect);
1725 
1726  // If we want to init permissions on admin users
1727  if ($reinitadminperms)
1728  {
1729  if (! class_exists('User')) {
1730  require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
1731  }
1732  $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."user WHERE admin = 1";
1733  dol_syslog(get_class($this)."::insert_permissions Search all admin users", LOG_DEBUG);
1734  $resqlseladmin=$this->db->query($sql,1);
1735  if ($resqlseladmin)
1736  {
1737  $num=$this->db->num_rows($resqlseladmin);
1738  $i=0;
1739  while ($i < $num)
1740  {
1741  $obj2=$this->db->fetch_object($resqlseladmin);
1742  dol_syslog(get_class($this)."::insert_permissions Add permission to user id=".$obj2->rowid);
1743  $tmpuser=new User($this->db);
1744  $tmpuser->fetch($obj2->rowid);
1745  if (!empty($tmpuser->id)) {
1746  $tmpuser->addrights($r_id, '', '', 0, 1);
1747  }
1748  $i++;
1749  }
1750  if (! empty($user->admin)) // Reload permission for current user if defined
1751  {
1752  // We reload permissions
1753  $user->clearrights();
1754  $user->getrights();
1755  }
1756  }
1757  else dol_print_error($this->db);
1758  }
1759  }
1760  }
1761  $this->db->free($resql);
1762  }
1763  else
1764  {
1765  $this->error=$this->db->lasterror();
1766  $err++;
1767  }
1768 
1769  return $err;
1770  }
1771 
1772 
1779  {
1780  global $conf;
1781 
1782  $err=0;
1783 
1784  $sql = "DELETE FROM ".MAIN_DB_PREFIX."rights_def";
1785  $sql.= " WHERE module = '".$this->db->escape($this->rights_class)."'";
1786  $sql.= " AND entity = ".$conf->entity;
1787  dol_syslog(get_class($this)."::delete_permissions", LOG_DEBUG);
1788  if (! $this->db->query($sql))
1789  {
1790  $this->error=$this->db->lasterror();
1791  $err++;
1792  }
1793 
1794  return $err;
1795  }
1796 
1797 
1803  function insert_menus()
1804  {
1805  global $user;
1806 
1807  if (! is_array($this->menu) || empty($this->menu)) return 0;
1808 
1809  require_once DOL_DOCUMENT_ROOT . '/core/class/menubase.class.php';
1810 
1811  $err=0;
1812 
1813  $this->db->begin();
1814 
1815  foreach ($this->menu as $key => $value)
1816  {
1817  $menu = new Menubase($this->db);
1818  $menu->menu_handler='all';
1819 
1820  //$menu->module=strtolower($this->name); TODO When right_class will be same than module name
1821  $menu->module=$this->rights_class;
1822 
1823  if (! $this->menu[$key]['fk_menu'])
1824  {
1825  $menu->fk_menu=0;
1826  }
1827  else
1828  {
1829  $foundparent=0;
1830  $fk_parent=$this->menu[$key]['fk_menu'];
1831  if (preg_match('/^r=/',$fk_parent)) // old deprecated method
1832  {
1833  $fk_parent=str_replace('r=','',$fk_parent);
1834  if (isset($this->menu[$fk_parent]['rowid']))
1835  {
1836  $menu->fk_menu=$this->menu[$fk_parent]['rowid'];
1837  $foundparent=1;
1838  }
1839  }
1840  elseif (preg_match('/^fk_mainmenu=([a-zA-Z0-9_]+),fk_leftmenu=([a-zA-Z0-9_]+)$/',$fk_parent,$reg))
1841  {
1842  $menu->fk_menu=-1;
1843  $menu->fk_mainmenu=$reg[1];
1844  $menu->fk_leftmenu=$reg[2];
1845  $foundparent=1;
1846  }
1847  elseif (preg_match('/^fk_mainmenu=([a-zA-Z0-9_]+)$/',$fk_parent,$reg))
1848  {
1849  $menu->fk_menu=-1;
1850  $menu->fk_mainmenu=$reg[1];
1851  $menu->fk_leftmenu='';
1852  $foundparent=1;
1853  }
1854  if (! $foundparent)
1855  {
1856  $this->error="ErrorBadDefinitionOfMenuArrayInModuleDescriptor";
1857  dol_syslog(get_class($this)."::insert_menus ".$this->error." ".$this->menu[$key]['fk_menu'], LOG_ERR);
1858  $err++;
1859  }
1860  }
1861  $menu->type=$this->menu[$key]['type'];
1862  $menu->mainmenu=isset($this->menu[$key]['mainmenu'])?$this->menu[$key]['mainmenu']:(isset($menu->fk_mainmenu)?$menu->fk_mainmenu:'');
1863  $menu->leftmenu=isset($this->menu[$key]['leftmenu'])?$this->menu[$key]['leftmenu']:'';
1864  $menu->titre=$this->menu[$key]['titre'];
1865  $menu->url=$this->menu[$key]['url'];
1866  $menu->langs=$this->menu[$key]['langs'];
1867  $menu->position=$this->menu[$key]['position'];
1868  $menu->perms=$this->menu[$key]['perms'];
1869  $menu->target=isset($this->menu[$key]['target'])?$this->menu[$key]['target']:'';
1870  $menu->user=$this->menu[$key]['user'];
1871  $menu->enabled=isset($this->menu[$key]['enabled'])?$this->menu[$key]['enabled']:0;
1872  $menu->position=$this->menu[$key]['position'];
1873 
1874  if (! $err)
1875  {
1876  $result=$menu->create($user); // Save menu entry into table llx_menu
1877  if ($result > 0)
1878  {
1879  $this->menu[$key]['rowid']=$result;
1880  }
1881  else
1882  {
1883  $this->error=$menu->error;
1884  dol_syslog(get_class($this).'::insert_menus result='.$result." ".$this->error, LOG_ERR);
1885  $err++;
1886  break;
1887  }
1888  }
1889  }
1890 
1891  if (! $err)
1892  {
1893  $this->db->commit();
1894  }
1895  else
1896  {
1897  dol_syslog(get_class($this)."::insert_menus ".$this->error, LOG_ERR);
1898  $this->db->rollback();
1899  }
1900 
1901  return $err;
1902  }
1903 
1904 
1910  function delete_menus()
1911  {
1912  global $conf;
1913 
1914  $err=0;
1915 
1916  //$module=strtolower($this->name); TODO When right_class will be same than module name
1917  $module=$this->rights_class;
1918 
1919  $sql = "DELETE FROM ".MAIN_DB_PREFIX."menu";
1920  $sql.= " WHERE module = '".$this->db->escape($module)."'";
1921  $sql.= " AND entity = ".$conf->entity;
1922 
1923  dol_syslog(get_class($this)."::delete_menus", LOG_DEBUG);
1924  $resql=$this->db->query($sql);
1925  if (! $resql)
1926  {
1927  $this->error=$this->db->lasterror();
1928  $err++;
1929  }
1930 
1931  return $err;
1932  }
1933 
1939  function create_dirs()
1940  {
1941  global $langs, $conf;
1942 
1943  $err=0;
1944 
1945  if (isset($this->dirs) && is_array($this->dirs))
1946  {
1947  foreach ($this->dirs as $key => $value)
1948  {
1949  $addtodatabase=0;
1950 
1951  if (! is_array($value)) $dir=$value; // Default simple mode
1952  else {
1953  $constname = $this->const_name."_DIR_";
1954  $dir = $this->dirs[$key][1];
1955  $addtodatabase = empty($this->dirs[$key][2])?'':$this->dirs[$key][2]; // Create constante in llx_const
1956  $subname = empty($this->dirs[$key][3])?'':strtoupper($this->dirs[$key][3]); // Add submodule name (ex: $conf->module->submodule->dir_output)
1957  $forcename = empty($this->dirs[$key][4])?'':strtoupper($this->dirs[$key][4]); // Change the module name if different
1958 
1959  if (! empty($forcename)) $constname = 'MAIN_MODULE_'.$forcename."_DIR_";
1960  if (! empty($subname)) $constname = $constname.$subname."_";
1961 
1962  $name = $constname.strtoupper($this->dirs[$key][0]);
1963  }
1964 
1965  // Define directory full path ($dir must start with "/")
1966  if (empty($conf->global->MAIN_MODULE_MULTICOMPANY) || $conf->entity == 1) $fulldir = DOL_DATA_ROOT.$dir;
1967  else $fulldir = DOL_DATA_ROOT."/".$conf->entity.$dir;
1968  // Create dir if it does not exists
1969  if (! empty($fulldir) && ! file_exists($fulldir))
1970  {
1971  if (dol_mkdir($fulldir, DOL_DATA_ROOT) < 0)
1972  {
1973  $this->error = $langs->trans("ErrorCanNotCreateDir",$fulldir);
1974  dol_syslog(get_class($this)."::_init ".$this->error, LOG_ERR);
1975  $err++;
1976  }
1977  }
1978 
1979  // Define the constant in database if requested (not the default mode)
1980  if (! empty($addtodatabase))
1981  {
1982  $result = $this->insert_dirs($name, $dir);
1983  if ($result) $err++;
1984  }
1985  }
1986  }
1987 
1988  return $err;
1989  }
1990 
1991 
2000  function insert_dirs($name,$dir)
2001  {
2002  global $conf;
2003 
2004  $err=0;
2005 
2006  $sql = "SELECT count(*)";
2007  $sql.= " FROM ".MAIN_DB_PREFIX."const";
2008  $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'";
2009  $sql.= " AND entity = ".$conf->entity;
2010 
2011  dol_syslog(get_class($this)."::insert_dirs", LOG_DEBUG);
2012  $result=$this->db->query($sql);
2013  if ($result)
2014  {
2015  $row = $this->db->fetch_row($result);
2016 
2017  if ($row[0] == 0)
2018  {
2019  $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)";
2020  $sql.= " VALUES (".$this->db->encrypt($name,1).",'chaine',".$this->db->encrypt($dir,1).",'Directory for module ".$this->name."','0',".$conf->entity.")";
2021 
2022  dol_syslog(get_class($this)."::insert_dirs", LOG_DEBUG);
2023  $this->db->query($sql);
2024  }
2025  }
2026  else
2027  {
2028  $this->error=$this->db->lasterror();
2029  $err++;
2030  }
2031 
2032  return $err;
2033  }
2034 
2035 
2041  function delete_dirs()
2042  {
2043  global $conf;
2044 
2045  $err=0;
2046 
2047  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
2048  $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->db->escape($this->const_name)."_DIR_%'";
2049  $sql.= " AND entity = ".$conf->entity;
2050 
2051  dol_syslog(get_class($this)."::delete_dirs", LOG_DEBUG);
2052  if (! $this->db->query($sql))
2053  {
2054  $this->error=$this->db->lasterror();
2055  $err++;
2056  }
2057 
2058  return $err;
2059  }
2060 
2067  {
2068  global $conf;
2069 
2070  $error=0;
2071 
2072  if (is_array($this->module_parts) && ! empty($this->module_parts))
2073  {
2074  foreach($this->module_parts as $key => $value)
2075  {
2076  if (is_array($value) && count($value) == 0) continue; // Discard empty arrays
2077 
2078  $entity=$conf->entity; // Reset the current entity
2079  $newvalue = $value;
2080 
2081  // Serialize array parameters
2082  if (is_array($value))
2083  {
2084  // Can defined other parameters
2085  if (is_array($value['data']) && ! empty($value['data']))
2086  {
2087  $newvalue = json_encode($value['data']);
2088  if (isset($value['entity'])) $entity = $value['entity'];
2089  }
2090  else if (isset($value['data']) && !is_array($value['data']))
2091  {
2092  $newvalue = $value['data'];
2093  if (isset($value['entity'])) $entity = $value['entity'];
2094  }
2095  else
2096  {
2097  $newvalue = json_encode($value);
2098  }
2099  }
2100 
2101  $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
2102  $sql.= "name";
2103  $sql.= ", type";
2104  $sql.= ", value";
2105  $sql.= ", note";
2106  $sql.= ", visible";
2107  $sql.= ", entity";
2108  $sql.= ")";
2109  $sql.= " VALUES (";
2110  $sql.= $this->db->encrypt($this->const_name."_".strtoupper($key), 1);
2111  $sql.= ", 'chaine'";
2112  $sql.= ", ".$this->db->encrypt($newvalue, 1);
2113  $sql.= ", null";
2114  $sql.= ", '0'";
2115  $sql.= ", ".$entity;
2116  $sql.= ")";
2117 
2118  dol_syslog(get_class($this)."::insert_const_".$key."", LOG_DEBUG);
2119  $resql=$this->db->query($sql,1);
2120  if (! $resql)
2121  {
2122  if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS')
2123  {
2124  $error++;
2125  $this->error=$this->db->lasterror();
2126  }
2127  else
2128  {
2129  dol_syslog(get_class($this)."::insert_const_".$key." Record already exists.", LOG_WARNING);
2130  }
2131  }
2132  }
2133  }
2134  return $error;
2135  }
2136 
2143  {
2144  global $conf;
2145 
2146  $err=0;
2147  $entity=$conf->entity;
2148 
2149  if (is_array($this->module_parts) && ! empty($this->module_parts))
2150  {
2151  foreach($this->module_parts as $key => $value)
2152  {
2153  // If entity is defined
2154  if (is_array($value) && isset($value['entity'])) $entity = $value['entity'];
2155 
2156  $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
2157  $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->db->escape($this->const_name)."_".strtoupper($key)."'";
2158  $sql.= " AND entity = ".$entity;
2159 
2160  dol_syslog(get_class($this)."::delete_const_".$key."", LOG_DEBUG);
2161  if (! $this->db->query($sql))
2162  {
2163  $this->error=$this->db->lasterror();
2164  $err++;
2165  }
2166  }
2167  }
2168  return $err;
2169  }
2170 
2181  public function init($options = '')
2182  {
2183  return $this->_init(array(), $options);
2184  }
2185 
2194  public function remove($options = '')
2195  {
2196  return $this->_remove(array(), $options);
2197  }
2198 }
getLastActivationInfo()
Gives the last author of activation.
_unactive()
Module deactivation.
Class DolibarrModules.
delete_dirs()
Removes directories.
insert_permissions($reinitadminperms=0, $force_entity=null, $notrigger=0)
Adds access rights.
_remove($array_sql, $options='')
Disable function.
</td >< tdclass="liste_titre"align="right"></td ></tr >< trclass="liste_titre">< inputtype="checkbox"onClick="toggle(this)"/> Ref p ref Label p label Duration p duration warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow img yes disabled img no img no< trclass="oddeven">< td >< inputtype="checkbox"class="check"name="'.$i.'"'.$disabled.'></td >< td >< inputtype="checkbox"class="check"name="choose'.$i.'"></td >< tdclass="nowrap"></td >< td >< inputtype="hidden"name="desc'.$i.'"value="'.dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:554
delete_permissions()
Removes access rights.
if(GETPOST('cancel','alpha')) if(!GETPOST('confirmmassaction','alpha')&&$massaction!= 'presend'&&$massaction!= 'confirm_presend')
Draft customers invoices.
Definition: list.php:147
Class to manage menu entries.
static getListOfPagesForBoxes()
Name of positions 0=Home, 1=...
Class to manage Dolibarr users.
Definition: user.class.php:39
getName()
Gives the translated module name if translation exists in admin.lang or into language files of module...
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
dolMd2Html($content, $parser='parsedown', $replaceimagepath=null)
Function to parse MD content into HTML.
Definition: parsemd.lib.php:32
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
insert_const()
Adds constants.
insert_dirs($name, $dir)
Adds directories definitions.
getImportDatasetLabel($r)
Gives translated label of an import dataset.
getExportDatasetLabel($r)
Gives translated label of an export dataset.
isCoreOrExternalModule()
Tells if module is core or external.
getLastActivationDate()
Gives the last date of activation.
delete_const()
Removes constants tagged 'deleteonunactive'.
delete_boxes()
Removes boxes.
insert_boxes($option='')
Adds boxes.
getDescLongReadmeFound()
Return path of file if a README file was found.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
insert_cronjobs()
Adds cronjobs.
getPublisher()
Gives the publisher name.
getChangeLog()
Gives the changelog.
getLangFilesArray()
Gives module related language files list.
delete_tabs()
Removes tabs.
getVersion($translated=1)
Gives module version (translated if param $translated is on) For 'experimental' modules, gives 'experimental' translation For 'dolibarr' modules, gives Dolibarr version.
dol_now($mode='gmt')
Return date for now.
delete_menus()
Removes menu entries.
delete_cronjobs()
Removes boxes.
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:427
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:104
getPublisherUrl()
Gives the publisher url.
delete_module_parts()
Removes generic parts.
getDescLong()
Gives the long description of a module.
_active()
Insert constants for module activation.
init($options= '')
Function called when module is enabled.
_init($array_sql, $options='')
Enables a module.
getDesc()
Gives the translated module description if translation exists in admin.lang or the default module des...
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->societe->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1013
run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='', $okerror='default')
Launch a sql file.
Definition: admin.lib.php:126
insert_module_parts()
Adds generic parts.
create_dirs()
Creates directories.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
__construct($db)
Constructor.
insert_menus()
Adds menu entries.
_load_tables($reldir)
Create tables and keys required by module.