usergroup.class.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. <?php
  2. /* Copyright (c) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (c) 2005-2018 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (c) 2005-2018 Regis Houssin <regis.houssin@inodbox.com>
  5. * Copyright (C) 2012 Florian Henry <florian.henry@open-concept.pro>
  6. * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
  7. * Copyright (C) 2014 Alexis Algoud <alexis@atm-consulting.fr>
  8. * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
  9. * Copyright (C) 2019 Abbes Bahfir <dolipar@dolipar.org>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 3 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  23. */
  24. /**
  25. * \file htdocs/user/class/usergroup.class.php
  26. * \brief File of class to manage user groups
  27. */
  28. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  29. if (!empty($conf->ldap->enabled)) {
  30. require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
  31. }
  32. /**
  33. * Class to manage user groups
  34. */
  35. class UserGroup extends CommonObject
  36. {
  37. /**
  38. * @var string ID to identify managed object
  39. */
  40. public $element = 'usergroup';
  41. /**
  42. * @var string Name of table without prefix where object is stored
  43. */
  44. public $table_element = 'usergroup';
  45. /**
  46. * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  47. * @var int
  48. */
  49. public $ismultientitymanaged = 1;
  50. /**
  51. * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
  52. */
  53. public $picto = 'group';
  54. /**
  55. * @var int Entity of group
  56. */
  57. public $entity;
  58. /**
  59. * @var string
  60. * @deprecated
  61. * @see $name
  62. */
  63. public $nom;
  64. /**
  65. * @var string name
  66. */
  67. public $name; // Name of group
  68. public $globalgroup; // Global group
  69. /**
  70. * Date creation record (datec)
  71. *
  72. * @var integer
  73. */
  74. public $datec;
  75. /**
  76. * Date modification record (tms)
  77. *
  78. * @var integer
  79. */
  80. public $datem;
  81. /**
  82. * @var string Description
  83. */
  84. public $note;
  85. public $members = array(); // Array of users
  86. public $nb_rights; // Number of rights granted to the user
  87. private $_tab_loaded = array(); // Array of cache of already loaded permissions
  88. public $oldcopy; // To contains a clone of this when we need to save old properties of object
  89. public $fields = array(
  90. 'rowid'=>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'),
  91. 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>5),
  92. 'nom'=>array('type'=>'varchar(180)', 'label'=>'Name', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Group name'),
  93. 'note' => array('type'=>'html', 'label'=>'Description', 'enabled'=>1, 'visible'=>1, 'position'=>20, 'notnull'=>-1,),
  94. 'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>50, 'notnull'=>1,),
  95. 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>60, 'notnull'=>1,),
  96. 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPDF', 'enabled'=>1, 'visible'=>0, 'position'=>100),
  97. );
  98. /**
  99. * @var string Field with ID of parent key if this field has a parent
  100. */
  101. public $fk_element = 'fk_usergroup';
  102. /**
  103. * @var array List of child tables. To test if we can delete object.
  104. */
  105. protected $childtables = array();
  106. /**
  107. * @var array List of child tables. To know object to delete on cascade.
  108. */
  109. protected $childtablesoncascade = array('usergroup_rights', 'usergroup_user');
  110. /**
  111. * Constructor de la classe
  112. *
  113. * @param DoliDb $db Database handler
  114. */
  115. public function __construct($db)
  116. {
  117. $this->db = $db;
  118. $this->nb_rights = 0;
  119. }
  120. /**
  121. * Charge un objet group avec toutes ses caracteristiques (except ->members array)
  122. *
  123. * @param int $id Id of group to load
  124. * @param string $groupname Name of group to load
  125. * @param boolean $load_members Load all members of the group
  126. * @return int <0 if KO, >0 if OK
  127. */
  128. public function fetch($id = '', $groupname = '', $load_members = true)
  129. {
  130. global $conf;
  131. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  132. if (!empty($groupname)) {
  133. $result = $this->fetchCommon(0, '', ' AND nom = \''.$this->db->escape($groupname).'\'');
  134. } else {
  135. $result = $this->fetchCommon($id);
  136. }
  137. $this->name = $this->nom; // For compatibility with field name
  138. if ($result) {
  139. if ($load_members) {
  140. $this->members = $this->listUsersForGroup();
  141. }
  142. return 1;
  143. } else {
  144. $this->error = $this->db->lasterror();
  145. return -1;
  146. }
  147. }
  148. /**
  149. * Return array of groups objects for a particular user
  150. *
  151. * @param int $userid User id to search
  152. * @param boolean $load_members Load all members of the group
  153. * @return array Array of groups objects
  154. */
  155. public function listGroupsForUser($userid, $load_members = true)
  156. {
  157. global $conf, $user;
  158. $ret = array();
  159. $sql = "SELECT g.rowid, ug.entity as usergroup_entity";
  160. $sql .= " FROM ".$this->db->prefix()."usergroup as g,";
  161. $sql .= " ".$this->db->prefix()."usergroup_user as ug";
  162. $sql .= " WHERE ug.fk_usergroup = g.rowid";
  163. $sql .= " AND ug.fk_user = ".((int) $userid);
  164. if (isModEnabled('multicompany') && $conf->entity == 1 && $user->admin && !$user->entity) {
  165. $sql .= " AND g.entity IS NOT NULL";
  166. } else {
  167. $sql .= " AND g.entity IN (0,".$conf->entity.")";
  168. }
  169. $sql .= " ORDER BY g.nom";
  170. dol_syslog(get_class($this)."::listGroupsForUser", LOG_DEBUG);
  171. $result = $this->db->query($sql);
  172. if ($result) {
  173. while ($obj = $this->db->fetch_object($result)) {
  174. if (!array_key_exists($obj->rowid, $ret)) {
  175. $newgroup = new UserGroup($this->db);
  176. $newgroup->fetch($obj->rowid, '', $load_members);
  177. $ret[$obj->rowid] = $newgroup;
  178. }
  179. $ret[$obj->rowid]->usergroup_entity[] = $obj->usergroup_entity;
  180. }
  181. $this->db->free($result);
  182. return $ret;
  183. } else {
  184. $this->error = $this->db->lasterror();
  185. return -1;
  186. }
  187. }
  188. /**
  189. * Return array of User objects for group this->id (or all if this->id not defined)
  190. *
  191. * @param string $excludefilter Filter to exclude. Do not use here a string coming from user input.
  192. * @param int $mode 0=Return array of user instance, 1=Return array of users id only
  193. * @return mixed Array of users or -1 on error
  194. */
  195. public function listUsersForGroup($excludefilter = '', $mode = 0)
  196. {
  197. global $conf, $user;
  198. $ret = array();
  199. $sql = "SELECT u.rowid";
  200. if (!empty($this->id)) {
  201. $sql .= ", ug.entity as usergroup_entity";
  202. }
  203. $sql .= " FROM ".$this->db->prefix()."user as u";
  204. if (!empty($this->id)) {
  205. $sql .= ", ".$this->db->prefix()."usergroup_user as ug";
  206. }
  207. $sql .= " WHERE 1 = 1";
  208. if (!empty($this->id)) {
  209. $sql .= " AND ug.fk_user = u.rowid";
  210. }
  211. if (!empty($this->id)) {
  212. $sql .= " AND ug.fk_usergroup = ".((int) $this->id);
  213. }
  214. if (isModEnabled('multicompany') && $conf->entity == 1 && $user->admin && !$user->entity) {
  215. $sql .= " AND u.entity IS NOT NULL";
  216. } else {
  217. $sql .= " AND u.entity IN (0,".$conf->entity.")";
  218. }
  219. if (!empty($excludefilter)) {
  220. $sql .= ' AND ('.$excludefilter.')';
  221. }
  222. dol_syslog(get_class($this)."::listUsersForGroup", LOG_DEBUG);
  223. $resql = $this->db->query($sql);
  224. if ($resql) {
  225. while ($obj = $this->db->fetch_object($resql)) {
  226. if (!array_key_exists($obj->rowid, $ret)) {
  227. if ($mode != 1) {
  228. $newuser = new User($this->db);
  229. $newuser->fetch($obj->rowid);
  230. $ret[$obj->rowid] = $newuser;
  231. } else {
  232. $ret[$obj->rowid] = $obj->rowid;
  233. }
  234. }
  235. if ($mode != 1 && !empty($obj->usergroup_entity)) {
  236. $ret[$obj->rowid]->usergroup_entity[] = $obj->usergroup_entity;
  237. }
  238. }
  239. $this->db->free($resql);
  240. return $ret;
  241. } else {
  242. $this->error = $this->db->lasterror();
  243. return -1;
  244. }
  245. }
  246. /**
  247. * Add a permission to a group
  248. *
  249. * @param int $rid id du droit a ajouter
  250. * @param string $allmodule Ajouter tous les droits du module allmodule
  251. * @param string $allperms Ajouter tous les droits du module allmodule, perms allperms
  252. * @param int $entity Entity to use
  253. * @return int > 0 if OK, < 0 if KO
  254. */
  255. public function addrights($rid, $allmodule = '', $allperms = '', $entity = 0)
  256. {
  257. global $conf, $user, $langs;
  258. $entity = (!empty($entity) ? $entity : $conf->entity);
  259. dol_syslog(get_class($this)."::addrights $rid, $allmodule, $allperms, $entity");
  260. $error = 0;
  261. $whereforadd = '';
  262. $this->db->begin();
  263. if (!empty($rid)) {
  264. $module = $perms = $subperms = '';
  265. // Si on a demande ajout d'un droit en particulier, on recupere
  266. // les caracteristiques (module, perms et subperms) de ce droit.
  267. $sql = "SELECT module, perms, subperms";
  268. $sql .= " FROM ".$this->db->prefix()."rights_def";
  269. $sql .= " WHERE id = ".((int) $rid);
  270. $sql .= " AND entity = ".((int) $entity);
  271. $result = $this->db->query($sql);
  272. if ($result) {
  273. $obj = $this->db->fetch_object($result);
  274. if ($obj) {
  275. $module = $obj->module;
  276. $perms = $obj->perms;
  277. $subperms = $obj->subperms;
  278. }
  279. } else {
  280. $error++;
  281. dol_print_error($this->db);
  282. }
  283. // Where pour la liste des droits a ajouter
  284. $whereforadd = "id=".((int) $rid);
  285. // Find also rights that are herited to add them too
  286. if ($subperms) {
  287. $whereforadd .= " OR (module='".$this->db->escape($module)."' AND perms='".$this->db->escape($perms)."' AND (subperms='lire' OR subperms='read'))";
  288. } elseif ($perms) {
  289. $whereforadd .= " OR (module='".$this->db->escape($module)."' AND (perms='lire' OR perms='read') AND subperms IS NULL)";
  290. }
  291. } else {
  292. // Where pour la liste des droits a ajouter
  293. if (!empty($allmodule)) {
  294. if ($allmodule == 'allmodules') {
  295. $whereforadd = 'allmodules';
  296. } else {
  297. $whereforadd = "module='".$this->db->escape($allmodule)."'";
  298. if (!empty($allperms)) {
  299. $whereforadd .= " AND perms='".$this->db->escape($allperms)."'";
  300. }
  301. }
  302. }
  303. }
  304. // Add permission of the list $whereforadd
  305. if (!empty($whereforadd)) {
  306. //print "$module-$perms-$subperms";
  307. $sql = "SELECT id";
  308. $sql .= " FROM ".$this->db->prefix()."rights_def";
  309. $sql .= " WHERE entity = ".((int) $entity);
  310. if (!empty($whereforadd) && $whereforadd != 'allmodules') {
  311. $sql .= " AND ".$whereforadd;
  312. }
  313. $result = $this->db->query($sql);
  314. if ($result) {
  315. $num = $this->db->num_rows($result);
  316. $i = 0;
  317. while ($i < $num) {
  318. $obj = $this->db->fetch_object($result);
  319. $nid = $obj->id;
  320. $sql = "DELETE FROM ".$this->db->prefix()."usergroup_rights WHERE fk_usergroup = ".((int) $this->id)." AND fk_id=".((int) $nid)." AND entity = ".((int) $entity);
  321. if (!$this->db->query($sql)) {
  322. $error++;
  323. }
  324. $sql = "INSERT INTO ".$this->db->prefix()."usergroup_rights (entity, fk_usergroup, fk_id) VALUES (".((int) $entity).", ".((int) $this->id).", ".((int) $nid).")";
  325. if (!$this->db->query($sql)) {
  326. $error++;
  327. }
  328. $i++;
  329. }
  330. } else {
  331. $error++;
  332. dol_print_error($this->db);
  333. }
  334. if (!$error) {
  335. $langs->load("other");
  336. $this->context = array('audit'=>$langs->trans("PermissionsAdd").($rid ? ' (id='.$rid.')' : ''));
  337. // Call trigger
  338. $result = $this->call_trigger('USERGROUP_MODIFY', $user);
  339. if ($result < 0) {
  340. $error++;
  341. }
  342. // End call triggers
  343. }
  344. }
  345. if ($error) {
  346. $this->db->rollback();
  347. return -$error;
  348. } else {
  349. $this->db->commit();
  350. return 1;
  351. }
  352. }
  353. /**
  354. * Remove a permission from group
  355. *
  356. * @param int $rid id du droit a retirer
  357. * @param string $allmodule Retirer tous les droits du module allmodule
  358. * @param string $allperms Retirer tous les droits du module allmodule, perms allperms
  359. * @param int $entity Entity to use
  360. * @return int > 0 if OK, < 0 if OK
  361. */
  362. public function delrights($rid, $allmodule = '', $allperms = '', $entity = 0)
  363. {
  364. global $conf, $user, $langs;
  365. $error = 0;
  366. $wherefordel = '';
  367. $entity = (!empty($entity) ? $entity : $conf->entity);
  368. $this->db->begin();
  369. if (!empty($rid)) {
  370. $module = $perms = $subperms = '';
  371. // Si on a demande supression d'un droit en particulier, on recupere
  372. // les caracteristiques module, perms et subperms de ce droit.
  373. $sql = "SELECT module, perms, subperms";
  374. $sql .= " FROM ".$this->db->prefix()."rights_def";
  375. $sql .= " WHERE id = ".((int) $rid);
  376. $sql .= " AND entity = ".((int) $entity);
  377. $result = $this->db->query($sql);
  378. if ($result) {
  379. $obj = $this->db->fetch_object($result);
  380. if ($obj) {
  381. $module = $obj->module;
  382. $perms = $obj->perms;
  383. $subperms = $obj->subperms;
  384. }
  385. } else {
  386. $error++;
  387. dol_print_error($this->db);
  388. }
  389. // Where for the list of permissions to delete
  390. $wherefordel = "id = ".((int) $rid);
  391. // Suppression des droits induits
  392. if ($subperms == 'lire' || $subperms == 'read') {
  393. $wherefordel .= " OR (module='".$this->db->escape($module)."' AND perms='".$this->db->escape($perms)."' AND subperms IS NOT NULL)";
  394. }
  395. if ($perms == 'lire' || $perms == 'read') {
  396. $wherefordel .= " OR (module='".$this->db->escape($module)."')";
  397. }
  398. // Pour compatibilite, si lowid = 0, on est en mode suppression de tout
  399. // TODO A virer quand sera gere par l'appelant
  400. //if (substr($rid,-1,1) == 0) $wherefordel="module='$module'";
  401. } else {
  402. // Add permission of the list $wherefordel
  403. if (!empty($allmodule)) {
  404. if ($allmodule == 'allmodules') {
  405. $wherefordel = 'allmodules';
  406. } else {
  407. $wherefordel = "module='".$this->db->escape($allmodule)."'";
  408. if (!empty($allperms)) {
  409. $wherefordel .= " AND perms='".$this->db->escape($allperms)."'";
  410. }
  411. }
  412. }
  413. }
  414. // Suppression des droits de la liste wherefordel
  415. if (!empty($wherefordel)) {
  416. //print "$module-$perms-$subperms";
  417. $sql = "SELECT id";
  418. $sql .= " FROM ".$this->db->prefix()."rights_def";
  419. $sql .= " WHERE entity = ".((int) $entity);
  420. if (!empty($wherefordel) && $wherefordel != 'allmodules') {
  421. $sql .= " AND ".$wherefordel;
  422. }
  423. $result = $this->db->query($sql);
  424. if ($result) {
  425. $num = $this->db->num_rows($result);
  426. $i = 0;
  427. while ($i < $num) {
  428. $nid = 0;
  429. $obj = $this->db->fetch_object($result);
  430. if ($obj) {
  431. $nid = $obj->id;
  432. }
  433. $sql = "DELETE FROM ".$this->db->prefix()."usergroup_rights";
  434. $sql .= " WHERE fk_usergroup = $this->id AND fk_id=".((int) $nid);
  435. $sql .= " AND entity = ".((int) $entity);
  436. if (!$this->db->query($sql)) {
  437. $error++;
  438. }
  439. $i++;
  440. }
  441. } else {
  442. $error++;
  443. dol_print_error($this->db);
  444. }
  445. if (!$error) {
  446. $langs->load("other");
  447. $this->context = array('audit'=>$langs->trans("PermissionsDelete").($rid ? ' (id='.$rid.')' : ''));
  448. // Call trigger
  449. $result = $this->call_trigger('USERGROUP_MODIFY', $user);
  450. if ($result < 0) {
  451. $error++;
  452. }
  453. // End call triggers
  454. }
  455. }
  456. if ($error) {
  457. $this->db->rollback();
  458. return -$error;
  459. } else {
  460. $this->db->commit();
  461. return 1;
  462. }
  463. }
  464. /**
  465. * Charge dans l'objet group, la liste des permissions auquels le groupe a droit
  466. *
  467. * @param string $moduletag Name of module we want permissions ('' means all)
  468. * @return int <0 if KO, >0 if OK
  469. */
  470. public function getrights($moduletag = '')
  471. {
  472. global $conf;
  473. if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag]) {
  474. // Rights for this module are already loaded, so we leave
  475. return;
  476. }
  477. if (!empty($this->all_permissions_are_loaded)) {
  478. // We already loaded all rights for this group, so we leave
  479. return;
  480. }
  481. /*
  482. * Recuperation des droits
  483. */
  484. $sql = "SELECT r.module, r.perms, r.subperms ";
  485. $sql .= " FROM ".$this->db->prefix()."usergroup_rights as u, ".$this->db->prefix()."rights_def as r";
  486. $sql .= " WHERE r.id = u.fk_id";
  487. $sql .= " AND r.entity = ".((int) $conf->entity);
  488. $sql .= " AND u.entity = ".((int) $conf->entity);
  489. $sql .= " AND u.fk_usergroup = ".((int) $this->id);
  490. $sql .= " AND r.perms IS NOT NULL";
  491. if ($moduletag) {
  492. $sql .= " AND r.module = '".$this->db->escape($moduletag)."'";
  493. }
  494. dol_syslog(get_class($this).'::getrights', LOG_DEBUG);
  495. $resql = $this->db->query($sql);
  496. if ($resql) {
  497. $num = $this->db->num_rows($resql);
  498. $i = 0;
  499. while ($i < $num) {
  500. $obj = $this->db->fetch_object($resql);
  501. if ($obj) {
  502. $module = $obj->module;
  503. $perms = $obj->perms;
  504. $subperms = $obj->subperms;
  505. if ($perms) {
  506. if (!isset($this->rights)) {
  507. $this->rights = new stdClass(); // For avoid error
  508. }
  509. if (!isset($this->rights->$module) || !is_object($this->rights->$module)) {
  510. $this->rights->$module = new stdClass();
  511. }
  512. if ($subperms) {
  513. if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) {
  514. $this->rights->$module->$perms = new stdClass();
  515. }
  516. if (empty($this->rights->$module->$perms->$subperms)) {
  517. $this->nb_rights++;
  518. }
  519. $this->rights->$module->$perms->$subperms = 1;
  520. } else {
  521. if (empty($this->rights->$module->$perms)) {
  522. $this->nb_rights++;
  523. }
  524. $this->rights->$module->$perms = 1;
  525. }
  526. }
  527. }
  528. $i++;
  529. }
  530. $this->db->free($resql);
  531. }
  532. if ($moduletag == '') {
  533. // Si module etait non defini, alors on a tout charge, on peut donc considerer
  534. // que les droits sont en cache (car tous charges) pour cet instance de group
  535. $this->all_permissions_are_loaded = 1;
  536. } else {
  537. // If module defined, we flag it as loaded into cache
  538. $this->_tab_loaded[$moduletag] = 1;
  539. }
  540. return 1;
  541. }
  542. /**
  543. * Delete a group
  544. *
  545. * @param User $user User that delete
  546. * @return int <0 if KO, > 0 if OK
  547. */
  548. public function delete(User $user)
  549. {
  550. return $this->deleteCommon($user);
  551. }
  552. /**
  553. * Create group into database
  554. *
  555. * @param int $notrigger 0=triggers enabled, 1=triggers disabled
  556. * @return int <0 if KO, >=0 if OK
  557. */
  558. public function create($notrigger = 0)
  559. {
  560. global $user, $conf;
  561. $this->datec = dol_now();
  562. if (!empty($this->name)) {
  563. $this->nom = $this->name; // Field for 'name' is called 'nom' in database
  564. }
  565. if (!isset($this->entity)) {
  566. $this->entity = $conf->entity; // If not defined, we use default value
  567. }
  568. return $this->createCommon($user, $notrigger);
  569. }
  570. /**
  571. * Update group into database
  572. *
  573. * @param int $notrigger 0=triggers enabled, 1=triggers disabled
  574. * @return int <0 if KO, >=0 if OK
  575. */
  576. public function update($notrigger = 0)
  577. {
  578. global $user, $conf;
  579. if (!empty($this->name)) {
  580. $this->nom = $this->name; // Field for 'name' is called 'nom' in database
  581. }
  582. return $this->updateCommon($user, $notrigger);
  583. }
  584. /**
  585. * Return label of status of user (active, inactive)
  586. *
  587. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  588. * @return string Label of status
  589. */
  590. public function getLibStatut($mode = 0)
  591. {
  592. return $this->LibStatut(0, $mode);
  593. }
  594. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  595. /**
  596. * Renvoi le libelle d'un statut donne
  597. *
  598. * @param int $status Id status
  599. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  600. * @return string Label of status
  601. */
  602. public function LibStatut($status, $mode = 0)
  603. {
  604. // phpcs:enable
  605. global $langs;
  606. $langs->load('users');
  607. return '';
  608. }
  609. /**
  610. * Return a link to the user card (with optionaly the picto)
  611. * Use this->id,this->lastname, this->firstname
  612. *
  613. * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small)
  614. * @param string $option On what the link point to ('nolink', 'permissions')
  615. * @param integer $notooltip 1=Disable tooltip on picto and name
  616. * @param string $morecss Add more css on link
  617. * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
  618. * @return string String with URL
  619. */
  620. public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
  621. {
  622. global $langs, $conf, $db, $hookmanager;
  623. global $dolibarr_main_authentication, $dolibarr_main_demo;
  624. global $menumanager;
  625. if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpicto) {
  626. $withpicto = 0;
  627. }
  628. $result = ''; $label = '';
  629. $label .= '<div class="centpercent">';
  630. $label .= img_picto('', 'group').' <u>'.$langs->trans("Group").'</u><br>';
  631. $label .= '<b>'.$langs->trans('Name').':</b> '.$this->name;
  632. $label .= '<br><b>'.$langs->trans("Description").':</b> '.$this->note;
  633. $label .= '</div>';
  634. if ($option == 'permissions') {
  635. $url = DOL_URL_ROOT.'/user/group/perms.php?id='.$this->id;
  636. } else {
  637. $url = DOL_URL_ROOT.'/user/group/card.php?id='.$this->id;
  638. }
  639. if ($option != 'nolink') {
  640. // Add param to save lastsearch_values or not
  641. $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
  642. if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
  643. $add_save_lastsearch_values = 1;
  644. }
  645. if ($add_save_lastsearch_values) {
  646. $url .= '&save_lastsearch_values=1';
  647. }
  648. }
  649. $linkclose = "";
  650. if (empty($notooltip)) {
  651. if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
  652. $langs->load("users");
  653. $label = $langs->trans("ShowGroup");
  654. $linkclose .= ' alt="'.dol_escape_htmltag($label, 1, 1).'"';
  655. }
  656. $linkclose .= ' title="'.dol_escape_htmltag($label, 1, 1).'"';
  657. $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
  658. }
  659. $linkstart = '<a href="'.$url.'"';
  660. $linkstart .= $linkclose.'>';
  661. $linkend = '</a>';
  662. $result = $linkstart;
  663. if ($withpicto) {
  664. $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
  665. }
  666. if ($withpicto != 2) {
  667. $result .= $this->name;
  668. }
  669. $result .= $linkend;
  670. global $action;
  671. $hookmanager->initHooks(array('groupdao'));
  672. $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
  673. $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
  674. if ($reshook > 0) {
  675. $result = $hookmanager->resPrint;
  676. } else {
  677. $result .= $hookmanager->resPrint;
  678. }
  679. return $result;
  680. }
  681. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
  682. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  683. /**
  684. * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
  685. *
  686. * @param array $info Info array loaded by _load_ldap_info
  687. * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
  688. * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
  689. * 2=Return key only (uid=qqq)
  690. * @return string DN
  691. */
  692. public function _load_ldap_dn($info, $mode = 0)
  693. {
  694. // phpcs:enable
  695. global $conf;
  696. $dn = '';
  697. if ($mode == 0) {
  698. $dn = $conf->global->LDAP_KEY_GROUPS."=".$info[$conf->global->LDAP_KEY_GROUPS].",".$conf->global->LDAP_GROUP_DN;
  699. }
  700. if ($mode == 1) {
  701. $dn = $conf->global->LDAP_GROUP_DN;
  702. }
  703. if ($mode == 2) {
  704. $dn = $conf->global->LDAP_KEY_GROUPS."=".$info[$conf->global->LDAP_KEY_GROUPS];
  705. }
  706. return $dn;
  707. }
  708. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
  709. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  710. /**
  711. * Initialize the info array (array of LDAP values) that will be used to call LDAP functions
  712. *
  713. * @return array Tableau info des attributs
  714. */
  715. public function _load_ldap_info()
  716. {
  717. // phpcs:enable
  718. global $conf;
  719. $info = array();
  720. // Object classes
  721. $info["objectclass"] = explode(',', $conf->global->LDAP_GROUP_OBJECT_CLASS);
  722. // Champs
  723. if ($this->name && !empty($conf->global->LDAP_GROUP_FIELD_FULLNAME)) {
  724. $info[$conf->global->LDAP_GROUP_FIELD_FULLNAME] = $this->name;
  725. }
  726. //if ($this->name && !empty($conf->global->LDAP_GROUP_FIELD_NAME)) $info[$conf->global->LDAP_GROUP_FIELD_NAME] = $this->name;
  727. if ($this->note && !empty($conf->global->LDAP_GROUP_FIELD_DESCRIPTION)) {
  728. $info[$conf->global->LDAP_GROUP_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note, 2);
  729. }
  730. if (!empty($conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS)) {
  731. $valueofldapfield = array();
  732. foreach ($this->members as $key => $val) { // This is array of users for group into dolibarr database.
  733. $muser = new User($this->db);
  734. $muser->fetch($val->id);
  735. $info2 = $muser->_load_ldap_info();
  736. $valueofldapfield[] = $muser->_load_ldap_dn($info2);
  737. }
  738. $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield) ? $valueofldapfield : '');
  739. }
  740. if (!empty($conf->global->LDAP_GROUP_FIELD_GROUPID)) {
  741. $info[$conf->global->LDAP_GROUP_FIELD_GROUPID] = $this->id;
  742. }
  743. return $info;
  744. }
  745. /**
  746. * Initialise an instance with random values.
  747. * Used to build previews or test instances.
  748. * id must be 0 if object instance is a specimen.
  749. *
  750. * @return void
  751. */
  752. public function initAsSpecimen()
  753. {
  754. global $conf, $user, $langs;
  755. // Initialise parametres
  756. $this->id = 0;
  757. $this->ref = 'SPECIMEN';
  758. $this->specimen = 1;
  759. $this->name = 'DOLIBARR GROUP SPECIMEN';
  760. $this->note = 'This is a note';
  761. $this->datec = time();
  762. $this->datem = time();
  763. // Members of this group is just me
  764. $this->members = array(
  765. $user->id => $user
  766. );
  767. }
  768. /**
  769. * Create a document onto disk according to template module.
  770. *
  771. * @param string $modele Force model to use ('' to not force)
  772. * @param Translate $outputlangs Object langs to use for output
  773. * @param int $hidedetails Hide details of lines
  774. * @param int $hidedesc Hide description
  775. * @param int $hideref Hide ref
  776. * @param null|array $moreparams Array to provide more information
  777. * @return int 0 if KO, 1 if OK
  778. */
  779. public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
  780. {
  781. global $conf, $user, $langs;
  782. $langs->load("user");
  783. // Positionne le modele sur le nom du modele a utiliser
  784. if (!dol_strlen($modele)) {
  785. if (!empty($conf->global->USERGROUP_ADDON_PDF)) {
  786. $modele = $conf->global->USERGROUP_ADDON_PDF;
  787. } else {
  788. $modele = 'grass';
  789. }
  790. }
  791. $modelpath = "core/modules/usergroup/doc/";
  792. return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
  793. }
  794. }