user.class.php 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507
  1. <?php
  2. /* Copyright (c) 2002-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (c) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
  4. * Copyright (c) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
  6. * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
  7. * Copyright (C) 2005-2015 Regis Houssin <regis.houssin@capnetworks.com>
  8. * Copyright (C) 2005 Lionel Cousteix <etm_ltd@tiscali.co.uk>
  9. * Copyright (C) 2011 Herve Prot <herve.prot@symeos.com>
  10. * Copyright (C) 2013-2014 Philippe Grand <philippe.grand@atoo-net.com>
  11. * Copyright (C) 2013 Alexandre Spangaro <aspangaro.dolibarr@gmail.com>
  12. * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 3 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  26. */
  27. /**
  28. * \file htdocs/user/class/user.class.php
  29. * \brief File of class to manage users
  30. * \ingroup core
  31. */
  32. require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
  33. /**
  34. * Class to manage Dolibarr users
  35. */
  36. class User extends CommonObject
  37. {
  38. public $element='user';
  39. public $table_element='user';
  40. protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  41. var $id=0;
  42. var $ref;
  43. var $ref_ext;
  44. var $ldap_sid;
  45. var $search_sid;
  46. var $lastname;
  47. var $firstname;
  48. var $gender;
  49. var $note;
  50. var $email;
  51. var $skype;
  52. var $job;
  53. var $signature;
  54. var $office_phone;
  55. var $office_fax;
  56. var $user_mobile;
  57. var $admin;
  58. var $login;
  59. var $api_key;
  60. var $entity;
  61. //! Clear password in memory
  62. var $pass;
  63. //! Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
  64. var $pass_indatabase;
  65. //! Encrypted password in database (always defined)
  66. var $pass_indatabase_crypted;
  67. var $datec;
  68. var $datem;
  69. //! If this is defined, it is an external user
  70. /**
  71. * @deprecated
  72. * @see socid
  73. */
  74. var $societe_id;
  75. /**
  76. * @deprecated
  77. * @see contactid
  78. */
  79. var $contact_id;
  80. var $socid;
  81. var $contactid;
  82. var $fk_member;
  83. var $fk_user;
  84. var $clicktodial_url;
  85. var $clicktodial_login;
  86. var $clicktodial_password;
  87. var $clicktodial_poste;
  88. var $datelastlogin;
  89. var $datepreviouslogin;
  90. var $statut;
  91. var $photo;
  92. var $lang;
  93. var $rights; // Array of permissions user->rights->permx
  94. var $all_permissions_are_loaded; /**< \private all_permissions_are_loaded */
  95. private $_tab_loaded=array(); // Array of cache of already loaded permissions
  96. var $conf; // To store personal config
  97. var $oldcopy; // To contains a clone of this when we need to save old properties of object
  98. var $users; // To store all tree of users hierarchy
  99. var $parentof; // To store an array of all parents for all ids.
  100. var $accountancy_code; // Accountancy code in prevision of the complete accountancy module
  101. var $thm; // Average cost of employee
  102. var $tjm; // Average cost of employee
  103. var $salary; // Monthly salary
  104. var $salaryextra; // Monthly salary extra
  105. var $weeklyhours; // Weekly hours
  106. var $color; // Define background color for user in agenda
  107. /**
  108. * Constructor de la classe
  109. *
  110. * @param DoliDb $db Database handler
  111. */
  112. function __construct($db)
  113. {
  114. $this->db = $db;
  115. // Preference utilisateur
  116. $this->liste_limit = 0;
  117. $this->clicktodial_loaded = 0;
  118. $this->all_permissions_are_loaded = 0;
  119. $this->admin=0;
  120. $this->conf = new stdClass();
  121. $this->rights = new stdClass();
  122. $this->rights->user = new stdClass();
  123. $this->rights->user->user = new stdClass();
  124. $this->rights->user->self = new stdClass();
  125. }
  126. /**
  127. * Load a user from database with its id or ref (login)
  128. *
  129. * @param int $id Si defini, id a utiliser pour recherche
  130. * @param string $login Si defini, login a utiliser pour recherche
  131. * @param string $sid Si defini, sid a utiliser pour recherche
  132. * @param int $loadpersonalconf Also load personal conf of user (in $user->conf->xxx)
  133. * @return int <0 if KO, 0 not found, >0 if OK
  134. */
  135. function fetch($id='', $login='',$sid='',$loadpersonalconf=1)
  136. {
  137. global $conf, $user;
  138. // Clean parameters
  139. $login=trim($login);
  140. // Get user
  141. $sql = "SELECT u.rowid, u.lastname, u.firstname, u.gender, u.email, u.job, u.skype, u.signature, u.office_phone, u.office_fax, u.user_mobile,";
  142. $sql.= " u.admin, u.login, u.note,";
  143. $sql.= " u.pass, u.pass_crypted, u.pass_temp, u.api_key,";
  144. $sql.= " u.fk_soc, u.fk_socpeople, u.fk_member, u.fk_user, u.ldap_sid,";
  145. $sql.= " u.statut, u.lang, u.entity,";
  146. $sql.= " u.datec as datec,";
  147. $sql.= " u.tms as datem,";
  148. $sql.= " u.datelastlogin as datel,";
  149. $sql.= " u.datepreviouslogin as datep,";
  150. $sql.= " u.photo as photo,";
  151. $sql.= " u.openid as openid,";
  152. $sql.= " u.accountancy_code,";
  153. $sql.= " u.thm,";
  154. $sql.= " u.tjm,";
  155. $sql.= " u.salary,";
  156. $sql.= " u.salaryextra,";
  157. $sql.= " u.weeklyhours,";
  158. $sql.= " u.color,";
  159. $sql.= " u.ref_int, u.ref_ext";
  160. $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
  161. if ((empty($conf->multicompany->enabled) || empty($conf->multicompany->transverse_mode)) && (! empty($user->entity)))
  162. {
  163. $sql.= " WHERE u.entity IN (0,".$conf->entity.")";
  164. }
  165. else
  166. {
  167. $sql.= " WHERE u.entity IS NOT NULL";
  168. }
  169. if ($sid) // permet une recherche du user par son SID ActiveDirectory ou Samba
  170. {
  171. $sql.= " AND (u.ldap_sid = '".$this->db->escape($sid)."' OR u.login = '".$this->db->escape($login)."') LIMIT 1";
  172. }
  173. else if ($login)
  174. {
  175. $sql.= " AND u.login = '".$this->db->escape($login)."'";
  176. }
  177. else
  178. {
  179. $sql.= " AND u.rowid = ".$id;
  180. }
  181. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  182. $result = $this->db->query($sql);
  183. if ($result)
  184. {
  185. $obj = $this->db->fetch_object($result);
  186. if ($obj)
  187. {
  188. $this->id = $obj->rowid;
  189. $this->ref = $obj->rowid;
  190. $this->ref_int = $obj->ref_int;
  191. $this->ref_ext = $obj->ref_ext;
  192. $this->ldap_sid = $obj->ldap_sid;
  193. $this->lastname = $obj->lastname;
  194. $this->firstname = $obj->firstname;
  195. $this->login = $obj->login;
  196. $this->gender = $obj->gender;
  197. $this->pass_indatabase = $obj->pass;
  198. $this->pass_indatabase_crypted = $obj->pass_crypted;
  199. $this->pass = $obj->pass;
  200. $this->pass_temp = $obj->pass_temp;
  201. $this->api_key = $obj->api_key;
  202. $this->office_phone = $obj->office_phone;
  203. $this->office_fax = $obj->office_fax;
  204. $this->user_mobile = $obj->user_mobile;
  205. $this->email = $obj->email;
  206. $this->skype = $obj->skype;
  207. $this->job = $obj->job;
  208. $this->signature = $obj->signature;
  209. $this->admin = $obj->admin;
  210. $this->note = $obj->note;
  211. $this->statut = $obj->statut;
  212. $this->photo = $obj->photo;
  213. $this->openid = $obj->openid;
  214. $this->lang = $obj->lang;
  215. $this->entity = $obj->entity;
  216. $this->accountancy_code = $obj->accountancy_code;
  217. $this->thm = $obj->thm;
  218. $this->tjm = $obj->tjm;
  219. $this->salary = $obj->salary;
  220. $this->salaryextra = $obj->salaryextra;
  221. $this->weeklyhours = $obj->weeklyhours;
  222. $this->color = $obj->color;
  223. $this->datec = $this->db->jdate($obj->datec);
  224. $this->datem = $this->db->jdate($obj->datem);
  225. $this->datelastlogin = $this->db->jdate($obj->datel);
  226. $this->datepreviouslogin = $this->db->jdate($obj->datep);
  227. $this->societe_id = $obj->fk_soc; // deprecated
  228. $this->contact_id = $obj->fk_socpeople; // deprecated
  229. $this->socid = $obj->fk_soc;
  230. $this->contactid = $obj->fk_socpeople;
  231. $this->fk_member = $obj->fk_member;
  232. $this->fk_user = $obj->fk_user;
  233. // Retreive all extrafield for thirdparty
  234. // fetch optionals attributes and labels
  235. require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
  236. $extrafields=new ExtraFields($this->db);
  237. $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true);
  238. $this->fetch_optionals($this->id,$extralabels);
  239. $this->db->free($result);
  240. }
  241. else
  242. {
  243. $this->error="USERNOTFOUND";
  244. dol_syslog(get_class($this)."::fetch user not found", LOG_DEBUG);
  245. $this->db->free($result);
  246. return 0;
  247. }
  248. }
  249. else
  250. {
  251. $this->error=$this->db->error();
  252. return -1;
  253. }
  254. // To get back the global configuration unique to the user
  255. if ($loadpersonalconf)
  256. {
  257. $sql = "SELECT param, value FROM ".MAIN_DB_PREFIX."user_param";
  258. $sql.= " WHERE fk_user = ".$this->id;
  259. $sql.= " AND entity = ".$conf->entity;
  260. //dol_syslog(get_class($this).'::fetch load personalized conf', LOG_DEBUG);
  261. $resql=$this->db->query($sql);
  262. if ($resql)
  263. {
  264. $num = $this->db->num_rows($resql);
  265. $i = 0;
  266. while ($i < $num)
  267. {
  268. $obj = $this->db->fetch_object($resql);
  269. $p=(! empty($obj->param)?$obj->param:'');
  270. if (! empty($p)) $this->conf->$p = $obj->value;
  271. $i++;
  272. }
  273. $this->db->free($resql);
  274. }
  275. else
  276. {
  277. $this->error=$this->db->error();
  278. return -2;
  279. }
  280. }
  281. return 1;
  282. }
  283. /**
  284. * Add a right to the user
  285. *
  286. * @param int $rid id du droit a ajouter
  287. * @param string $allmodule Ajouter tous les droits du module allmodule
  288. * @param string $allperms Ajouter tous les droits du module allmodule, perms allperms
  289. * @param int $entity Entity to use
  290. * @return int > 0 if OK, < 0 if KO
  291. */
  292. function addrights($rid, $allmodule='', $allperms='', $entity='')
  293. {
  294. global $conf;
  295. $entity = (! empty($entity)?$entity:$conf->entity);
  296. dol_syslog(get_class($this)."::addrights $rid, $allmodule, $allperms, $entity");
  297. $err=0;
  298. $whereforadd='';
  299. $this->db->begin();
  300. if (! empty($rid))
  301. {
  302. // Si on a demande ajout d'un droit en particulier, on recupere
  303. // les caracteristiques (module, perms et subperms) de ce droit.
  304. $sql = "SELECT module, perms, subperms";
  305. $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
  306. $sql.= " WHERE id = '".$this->db->escape($rid)."'";
  307. $sql.= " AND entity = ".$entity;
  308. $result=$this->db->query($sql);
  309. if ($result) {
  310. $obj = $this->db->fetch_object($result);
  311. $module=$obj->module;
  312. $perms=$obj->perms;
  313. $subperms=$obj->subperms;
  314. }
  315. else {
  316. $err++;
  317. dol_print_error($this->db);
  318. }
  319. // Where pour la liste des droits a ajouter
  320. $whereforadd="id=".$this->db->escape($rid);
  321. // Ajout des droits induits
  322. if (! empty($subperms)) $whereforadd.=" OR (module='$module' AND perms='$perms' AND (subperms='lire' OR subperms='read'))";
  323. else if (! empty($perms)) $whereforadd.=" OR (module='$module' AND (perms='lire' OR perms='read') AND subperms IS NULL)";
  324. }
  325. else {
  326. // On a pas demande un droit en particulier mais une liste de droits
  327. // sur la base d'un nom de module de de perms
  328. // Where pour la liste des droits a ajouter
  329. if (! empty($allmodule)) $whereforadd="module='".$this->db->escape($allmodule)."'";
  330. if (! empty($allperms)) $whereforadd=" AND perms='".$this->db->escape($allperms)."'";
  331. }
  332. // Ajout des droits trouves grace au critere whereforadd
  333. if (! empty($whereforadd))
  334. {
  335. //print "$module-$perms-$subperms";
  336. $sql = "SELECT id";
  337. $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
  338. $sql.= " WHERE ".$whereforadd;
  339. $sql.= " AND entity = ".$entity;
  340. $result=$this->db->query($sql);
  341. if ($result)
  342. {
  343. $num = $this->db->num_rows($result);
  344. $i = 0;
  345. while ($i < $num)
  346. {
  347. $obj = $this->db->fetch_object($result);
  348. $nid = $obj->id;
  349. $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id." AND fk_id=".$nid;
  350. if (! $this->db->query($sql)) $err++;
  351. $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (fk_user, fk_id) VALUES (".$this->id.", ".$nid.")";
  352. if (! $this->db->query($sql)) $err++;
  353. $i++;
  354. }
  355. }
  356. else
  357. {
  358. $err++;
  359. dol_print_error($this->db);
  360. }
  361. }
  362. if ($err) {
  363. $this->db->rollback();
  364. return -$err;
  365. }
  366. else {
  367. $this->db->commit();
  368. return 1;
  369. }
  370. }
  371. /**
  372. * Remove a right to the user
  373. *
  374. * @param int $rid Id du droit a retirer
  375. * @param string $allmodule Retirer tous les droits du module allmodule
  376. * @param string $allperms Retirer tous les droits du module allmodule, perms allperms
  377. * @param int $entity Entity to use
  378. * @return int > 0 if OK, < 0 if OK
  379. */
  380. function delrights($rid, $allmodule='', $allperms='', $entity='')
  381. {
  382. global $conf;
  383. $err=0;
  384. $wherefordel='';
  385. $entity = (! empty($entity)?$entity:$conf->entity);
  386. $this->db->begin();
  387. if (! empty($rid))
  388. {
  389. // Si on a demande supression d'un droit en particulier, on recupere
  390. // les caracteristiques module, perms et subperms de ce droit.
  391. $sql = "SELECT module, perms, subperms";
  392. $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
  393. $sql.= " WHERE id = '".$this->db->escape($rid)."'";
  394. $sql.= " AND entity = ".$entity;
  395. $result=$this->db->query($sql);
  396. if ($result) {
  397. $obj = $this->db->fetch_object($result);
  398. $module=$obj->module;
  399. $perms=$obj->perms;
  400. $subperms=$obj->subperms;
  401. }
  402. else {
  403. $err++;
  404. dol_print_error($this->db);
  405. }
  406. // Where pour la liste des droits a supprimer
  407. $wherefordel="id=".$this->db->escape($rid);
  408. // Suppression des droits induits
  409. if ($subperms=='lire' || $subperms=='read') $wherefordel.=" OR (module='$module' AND perms='$perms' AND subperms IS NOT NULL)";
  410. if ($perms=='lire' || $perms=='read') $wherefordel.=" OR (module='$module')";
  411. }
  412. else {
  413. // On a demande suppression d'un droit sur la base d'un nom de module ou perms
  414. // Where pour la liste des droits a supprimer
  415. if (! empty($allmodule)) $wherefordel="module='".$this->db->escape($allmodule)."'";
  416. if (! empty($allperms)) $wherefordel=" AND perms='".$this->db->escape($allperms)."'";
  417. }
  418. // Suppression des droits selon critere defini dans wherefordel
  419. if (! empty($wherefordel))
  420. {
  421. //print "$module-$perms-$subperms";
  422. $sql = "SELECT id";
  423. $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
  424. $sql.= " WHERE $wherefordel";
  425. $sql.= " AND entity = ".$entity;
  426. $result=$this->db->query($sql);
  427. if ($result)
  428. {
  429. $num = $this->db->num_rows($result);
  430. $i = 0;
  431. while ($i < $num)
  432. {
  433. $obj = $this->db->fetch_object($result);
  434. $nid = $obj->id;
  435. $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights";
  436. $sql.= " WHERE fk_user = ".$this->id." AND fk_id=".$nid;
  437. if (! $this->db->query($sql)) $err++;
  438. $i++;
  439. }
  440. }
  441. else
  442. {
  443. $err++;
  444. dol_print_error($this->db);
  445. }
  446. }
  447. if ($err) {
  448. $this->db->rollback();
  449. return -$err;
  450. }
  451. else {
  452. $this->db->commit();
  453. return 1;
  454. }
  455. }
  456. /**
  457. * Clear all permissions array of user
  458. *
  459. * @return void
  460. * @see getrights
  461. */
  462. function clearrights()
  463. {
  464. dol_syslog(get_class($this)."::clearrights reset user->rights");
  465. $this->rights='';
  466. $this->all_permissions_are_loaded=false;
  467. $this->_tab_loaded=array();
  468. }
  469. /**
  470. * Load permissions granted to user into object user
  471. *
  472. * @param string $moduletag Limit permission for a particular module ('' by default means load all permissions)
  473. * @return void
  474. * @see clearrights
  475. */
  476. function getrights($moduletag='')
  477. {
  478. global $conf;
  479. if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag])
  480. {
  481. // Le fichier de ce module est deja charge
  482. return;
  483. }
  484. if ($this->all_permissions_are_loaded)
  485. {
  486. // Si les permissions ont deja ete charge pour ce user, on quitte
  487. return;
  488. }
  489. // Recuperation des droits utilisateurs + recuperation des droits groupes
  490. // D'abord les droits utilisateurs
  491. $sql = "SELECT r.module, r.perms, r.subperms";
  492. $sql.= " FROM ".MAIN_DB_PREFIX."user_rights as ur";
  493. $sql.= ", ".MAIN_DB_PREFIX."rights_def as r";
  494. $sql.= " WHERE r.id = ur.fk_id";
  495. $sql.= " AND r.entity IN (0,".(! empty($conf->multicompany->enabled) && ! empty($conf->multicompany->transverse_mode)?"1,":"").$conf->entity.")";
  496. $sql.= " AND ur.fk_user= ".$this->id;
  497. $sql.= " AND r.perms IS NOT NULL";
  498. if ($moduletag) $sql.= " AND r.module = '".$this->db->escape($moduletag)."'";
  499. dol_syslog(get_class($this).'::getrights', LOG_DEBUG);
  500. $resql = $this->db->query($sql);
  501. if ($resql)
  502. {
  503. $num = $this->db->num_rows($resql);
  504. $i = 0;
  505. while ($i < $num)
  506. {
  507. $obj = $this->db->fetch_object($resql);
  508. $module=$obj->module;
  509. $perms=$obj->perms;
  510. $subperms=$obj->subperms;
  511. if ($perms)
  512. {
  513. if (! isset($this->rights) || ! is_object($this->rights)) $this->rights = new stdClass(); // For avoid error
  514. if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
  515. if ($subperms)
  516. {
  517. if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
  518. $this->rights->$module->$perms->$subperms = 1;
  519. }
  520. else
  521. {
  522. $this->rights->$module->$perms = 1;
  523. }
  524. }
  525. $i++;
  526. }
  527. $this->db->free($resql);
  528. }
  529. // Maintenant les droits groupes
  530. $sql = "SELECT r.module, r.perms, r.subperms";
  531. $sql.= " FROM ".MAIN_DB_PREFIX."usergroup_rights as gr,";
  532. $sql.= " ".MAIN_DB_PREFIX."usergroup_user as gu,";
  533. $sql.= " ".MAIN_DB_PREFIX."rights_def as r";
  534. $sql.= " WHERE r.id = gr.fk_id";
  535. if (! empty($conf->multicompany->enabled) && ! empty($conf->multicompany->transverse_mode)) {
  536. $sql.= " AND gu.entity IN (0,".$conf->entity.")";
  537. } else {
  538. $sql.= " AND r.entity = ".$conf->entity;
  539. }
  540. $sql.= " AND gr.fk_usergroup = gu.fk_usergroup";
  541. $sql.= " AND gu.fk_user = ".$this->id;
  542. $sql.= " AND r.perms IS NOT NULL";
  543. if ($moduletag) $sql.= " AND r.module = '".$this->db->escape($moduletag)."'";
  544. dol_syslog(get_class($this).'::getrights', LOG_DEBUG);
  545. $resql = $this->db->query($sql);
  546. if ($resql)
  547. {
  548. $num = $this->db->num_rows($resql);
  549. $i = 0;
  550. while ($i < $num)
  551. {
  552. $obj = $this->db->fetch_object($resql);
  553. $module=$obj->module;
  554. $perms=$obj->perms;
  555. $subperms=$obj->subperms;
  556. if ($perms)
  557. {
  558. if (! isset($this->rights) || ! is_object($this->rights)) $this->rights = new stdClass(); // For avoid error
  559. if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
  560. if ($subperms)
  561. {
  562. if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
  563. $this->rights->$module->$perms->$subperms = 1;
  564. }
  565. else
  566. {
  567. $this->rights->$module->$perms = 1;
  568. }
  569. }
  570. $i++;
  571. }
  572. $this->db->free($resql);
  573. }
  574. // For backward compatibility
  575. if (isset($this->rights->propale) && ! isset($this->rights->propal)) $this->rights->propal = $this->rights->propale;
  576. if (isset($this->rights->propal) && ! isset($this->rights->propale)) $this->rights->propale = $this->rights->propal;
  577. if (! $moduletag)
  578. {
  579. // Si module etait non defini, alors on a tout charge, on peut donc considerer
  580. // que les droits sont en cache (car tous charges) pour cet instance de user
  581. $this->all_permissions_are_loaded=1;
  582. }
  583. else
  584. {
  585. // Si module defini, on le marque comme charge en cache
  586. $this->_tab_loaded[$moduletag]=1;
  587. }
  588. }
  589. /**
  590. * Change status of a user
  591. *
  592. * @param int $statut Status to set
  593. * @return int <0 if KO, 0 if nothing is done, >0 if OK
  594. */
  595. function setstatus($statut)
  596. {
  597. global $conf,$langs,$user;
  598. $error=0;
  599. // Check parameters
  600. if ($this->statut == $statut) return 0;
  601. else $this->statut = $statut;
  602. $this->db->begin();
  603. // Deactivate user
  604. $sql = "UPDATE ".MAIN_DB_PREFIX."user";
  605. $sql.= " SET statut = ".$this->statut;
  606. $sql.= " WHERE rowid = ".$this->id;
  607. $result = $this->db->query($sql);
  608. dol_syslog(get_class($this)."::setstatus", LOG_DEBUG);
  609. if ($result)
  610. {
  611. // Call trigger
  612. $result=$this->call_trigger('USER_ENABLEDISABLE',$user);
  613. if ($result < 0) { $error++; }
  614. // End call triggers
  615. }
  616. if ($error)
  617. {
  618. $this->db->rollback();
  619. return -$error;
  620. }
  621. else
  622. {
  623. $this->db->commit();
  624. return 1;
  625. }
  626. }
  627. /**
  628. * Delete the user
  629. *
  630. * @return int <0 if KO, >0 if OK
  631. */
  632. function delete()
  633. {
  634. global $user,$conf,$langs;
  635. $error=0;
  636. $this->db->begin();
  637. $this->fetch($this->id);
  638. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  639. // Remove rights
  640. $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id;
  641. if (! $error && ! $this->db->query($sql))
  642. {
  643. $error++;
  644. $this->error = $this->db->lasterror();
  645. }
  646. // Remove group
  647. $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user WHERE fk_user = ".$this->id;
  648. if (! $error && ! $this->db->query($sql))
  649. {
  650. $error++;
  651. $this->error = $this->db->lasterror();
  652. }
  653. // If contact, remove link
  654. if ($this->contact_id)
  655. {
  656. $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET fk_user_creat = null WHERE rowid = ".$this->contact_id;
  657. if (! $error && ! $this->db->query($sql))
  658. {
  659. $error++;
  660. $this->error = $this->db->lasterror();
  661. }
  662. }
  663. // Remove extrafields
  664. if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
  665. {
  666. $result=$this->deleteExtraFields();
  667. if ($result < 0)
  668. {
  669. $error++;
  670. dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
  671. }
  672. }
  673. // Remove user
  674. if (! $error)
  675. {
  676. $sql = "DELETE FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->id;
  677. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  678. if (! $this->db->query($sql))
  679. {
  680. $error++;
  681. $this->error = $this->db->lasterror();
  682. }
  683. }
  684. if (! $error)
  685. {
  686. // Call trigger
  687. $result=$this->call_trigger('USER_DELETE',$user);
  688. if ($result < 0)
  689. {
  690. $error++;
  691. $this->db->rollback();
  692. return -1;
  693. }
  694. // End call triggers
  695. $this->db->commit();
  696. return 1;
  697. }
  698. else
  699. {
  700. $this->db->rollback();
  701. return -1;
  702. }
  703. }
  704. /**
  705. * Create a user into database
  706. *
  707. * @param User $user Objet user doing creation
  708. * @param int $notrigger 1=do not execute triggers, 0 otherwise
  709. * @return int <0 if KO, id of created user if OK
  710. */
  711. function create($user,$notrigger=0)
  712. {
  713. global $conf,$langs;
  714. global $mysoc;
  715. // Clean parameters
  716. $this->login = trim($this->login);
  717. if (! isset($this->entity)) $this->entity=$conf->entity; // If not defined, we use default value
  718. dol_syslog(get_class($this)."::create login=".$this->login.", user=".(is_object($user)?$user->id:''), LOG_DEBUG);
  719. // Check parameters
  720. if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
  721. {
  722. $langs->load("errors");
  723. $this->error = $langs->trans("ErrorBadEMail",$this->email);
  724. return -1;
  725. }
  726. if (empty($this->login))
  727. {
  728. $langs->load("errors");
  729. $this->error = $langs->trans("ErrorFieldRequired",$this->login);
  730. return -1;
  731. }
  732. $this->datec = dol_now();
  733. $error=0;
  734. $this->db->begin();
  735. $sql = "SELECT login FROM ".MAIN_DB_PREFIX."user";
  736. $sql.= " WHERE login ='".$this->db->escape($this->login)."'";
  737. $sql.= " AND entity IN (0,".$this->db->escape($conf->entity).")";
  738. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  739. $resql=$this->db->query($sql);
  740. if ($resql)
  741. {
  742. $num = $this->db->num_rows($resql);
  743. $this->db->free($resql);
  744. if ($num)
  745. {
  746. $this->error = 'ErrorLoginAlreadyExists';
  747. dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
  748. $this->db->rollback();
  749. return -6;
  750. }
  751. else
  752. {
  753. $sql = "INSERT INTO ".MAIN_DB_PREFIX."user (datec,login,ldap_sid,entity)";
  754. $sql.= " VALUES('".$this->db->idate($this->datec)."','".$this->db->escape($this->login)."','".$this->db->escape($this->ldap_sid)."',".$this->db->escape($this->entity).")";
  755. $result=$this->db->query($sql);
  756. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  757. if ($result)
  758. {
  759. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."user");
  760. // Set default rights
  761. if ($this->set_default_rights() < 0)
  762. {
  763. $this->error='ErrorFailedToSetDefaultRightOfUser';
  764. $this->db->rollback();
  765. return -5;
  766. }
  767. // Update minor fields
  768. $result = $this->update($user,1,1);
  769. if ($result < 0)
  770. {
  771. $this->db->rollback();
  772. return -4;
  773. }
  774. if (! empty($conf->global->STOCK_USERSTOCK_AUTOCREATE))
  775. {
  776. require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
  777. $langs->load("stocks");
  778. $entrepot = new Entrepot($this->db);
  779. $entrepot->libelle = $langs->trans("PersonalStock",$this->getFullName($langs));
  780. $entrepot->description = $langs->trans("ThisWarehouseIsPersonalStock",$this->getFullName($langs));
  781. $entrepot->statut = 1;
  782. $entrepot->country_id = $mysoc->country_id;
  783. $entrepot->create($user);
  784. }
  785. if (! $notrigger)
  786. {
  787. // Call trigger
  788. $result=$this->call_trigger('USER_CREATE',$user);
  789. if ($result < 0) { $error++; }
  790. // End call triggers
  791. }
  792. if (! $error)
  793. {
  794. $this->db->commit();
  795. return $this->id;
  796. }
  797. else
  798. {
  799. //$this->error=$interface->error;
  800. dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
  801. $this->db->rollback();
  802. return -3;
  803. }
  804. }
  805. else
  806. {
  807. $this->error=$this->db->lasterror();
  808. $this->db->rollback();
  809. return -2;
  810. }
  811. }
  812. }
  813. else
  814. {
  815. $this->error=$this->db->lasterror();
  816. $this->db->rollback();
  817. return -1;
  818. }
  819. }
  820. /**
  821. * Create a user from a contact object. User will be internal but if contact is linked to a third party, user will be external
  822. *
  823. * @param Contact $contact Object for source contact
  824. * @param string $login Login to force
  825. * @param string $password Password to force
  826. * @return int <0 if error, if OK returns id of created user
  827. */
  828. function create_from_contact($contact,$login='',$password='')
  829. {
  830. global $conf,$user,$langs;
  831. $error=0;
  832. // Positionne parametres
  833. $this->admin = 0;
  834. $this->lastname = $contact->lastname;
  835. $this->firstname = $contact->firstname;
  836. $this->gender = $contact->gender;
  837. $this->email = $contact->email;
  838. $this->skype = $contact->skype;
  839. $this->office_phone = $contact->phone_pro;
  840. $this->office_fax = $contact->fax;
  841. $this->user_mobile = $contact->phone_mobile;
  842. $this->address = $contact->address;
  843. $this->zip = $contact->zip;
  844. $this->town = $contact->town;
  845. $this->state_id = $contact->state_id;
  846. $this->country_id = $contact->country_id;
  847. if (empty($login)) $login=strtolower(substr($contact->firstname, 0, 4)) . strtolower(substr($contact->lastname, 0, 4));
  848. $this->login = $login;
  849. $this->db->begin();
  850. // Cree et positionne $this->id
  851. $result=$this->create($user);
  852. if ($result > 0)
  853. {
  854. $sql = "UPDATE ".MAIN_DB_PREFIX."user";
  855. $sql.= " SET fk_socpeople=".$contact->id;
  856. if ($contact->socid) $sql.=", fk_soc=".$contact->socid;
  857. $sql.= " WHERE rowid=".$this->id;
  858. $resql=$this->db->query($sql);
  859. dol_syslog(get_class($this)."::create_from_contact", LOG_DEBUG);
  860. if ($resql)
  861. {
  862. $this->context['createfromcontact']='createfromcontact';
  863. // Call trigger
  864. $result=$this->call_trigger('USER_CREATE',$user);
  865. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  866. // End call triggers
  867. $this->db->commit();
  868. return $this->id;
  869. }
  870. else
  871. {
  872. $this->error=$this->db->error();
  873. $this->db->rollback();
  874. return -1;
  875. }
  876. }
  877. else
  878. {
  879. // $this->error deja positionne
  880. dol_syslog(get_class($this)."::create_from_contact - 0");
  881. $this->db->rollback();
  882. return $result;
  883. }
  884. }
  885. /**
  886. * Create a user into database from a member object
  887. *
  888. * @param Adherent $member Object member source
  889. * @param string $login Login to force
  890. * @return int <0 if KO, if OK, return id of created account
  891. */
  892. function create_from_member($member,$login='')
  893. {
  894. global $conf,$user,$langs;
  895. // Positionne parametres
  896. $this->admin = 0;
  897. $this->lastname = $member->lastname;
  898. $this->firstname = $member->firstname;
  899. $this->gender = $member->gender;
  900. $this->email = $member->email;
  901. $this->fk_member = $member->id;
  902. $this->pass = $member->pass;
  903. $this->address = $member->address;
  904. $this->zip = $member->zip;
  905. $this->town = $member->town;
  906. $this->state_id = $member->state_id;
  907. $this->country_id = $member->country_id;
  908. if (empty($login)) $login=strtolower(substr($member->firstname, 0, 4)) . strtolower(substr($member->lastname, 0, 4));
  909. $this->login = $login;
  910. $this->db->begin();
  911. // Create and set $this->id
  912. $result=$this->create($user);
  913. if ($result > 0)
  914. {
  915. $newpass=$this->setPassword($user,$this->pass);
  916. if (is_numeric($newpass) && $newpass < 0) $result=-2;
  917. if ($result > 0 && $member->fk_soc) // If member is linked to a thirdparty
  918. {
  919. $sql = "UPDATE ".MAIN_DB_PREFIX."user";
  920. $sql.= " SET fk_soc=".$member->fk_soc;
  921. $sql.= " WHERE rowid=".$this->id;
  922. dol_syslog(get_class($this)."::create_from_member", LOG_DEBUG);
  923. $resql=$this->db->query($sql);
  924. if ($resql)
  925. {
  926. $this->db->commit();
  927. return $this->id;
  928. }
  929. else
  930. {
  931. $this->error=$this->db->lasterror();
  932. $this->db->rollback();
  933. return -1;
  934. }
  935. }
  936. }
  937. if ($result > 0)
  938. {
  939. $this->db->commit();
  940. return $this->id;
  941. }
  942. else
  943. {
  944. // $this->error deja positionne
  945. $this->db->rollback();
  946. return -2;
  947. }
  948. }
  949. /**
  950. * Assign rights by default
  951. *
  952. * @return integer erreur <0, si ok renvoi le nbre de droits par defaut positionnes
  953. */
  954. function set_default_rights()
  955. {
  956. global $conf;
  957. $sql = "SELECT id FROM ".MAIN_DB_PREFIX."rights_def";
  958. $sql.= " WHERE bydefault = 1";
  959. $sql.= " AND entity = ".$conf->entity;
  960. $resql=$this->db->query($sql);
  961. if ($resql)
  962. {
  963. $num = $this->db->num_rows($resql);
  964. $i = 0;
  965. $rd = array();
  966. while ($i < $num)
  967. {
  968. $row = $this->db->fetch_row($resql);
  969. $rd[$i] = $row[0];
  970. $i++;
  971. }
  972. $this->db->free($resql);
  973. }
  974. $i = 0;
  975. while ($i < $num)
  976. {
  977. $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = $this->id AND fk_id=$rd[$i]";
  978. $result=$this->db->query($sql);
  979. $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (fk_user, fk_id) VALUES ($this->id, $rd[$i])";
  980. $result=$this->db->query($sql);
  981. if (! $result) return -1;
  982. $i++;
  983. }
  984. return $i;
  985. }
  986. /**
  987. * Update a user into database (and also password if this->pass is defined)
  988. *
  989. * @param User $user User qui fait la mise a jour
  990. * @param int $notrigger 1 ne declenche pas les triggers, 0 sinon
  991. * @param int $nosyncmember 0=Synchronize linked member (standard info), 1=Do not synchronize linked member
  992. * @param int $nosyncmemberpass 0=Synchronize linked member (password), 1=Do not synchronize linked member
  993. * @return int <0 si KO, >=0 si OK
  994. */
  995. function update($user,$notrigger=0,$nosyncmember=0,$nosyncmemberpass=0)
  996. {
  997. global $conf, $langs, $hookmanager;
  998. $nbrowsaffected=0;
  999. $error=0;
  1000. dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncmember=".$nosyncmember.", nosyncmemberpass=".$nosyncmemberpass);
  1001. // Clean parameters
  1002. $this->lastname = trim($this->lastname);
  1003. $this->firstname = trim($this->firstname);
  1004. $this->login = trim($this->login);
  1005. $this->gender = trim($this->gender);
  1006. $this->pass = trim($this->pass);
  1007. $this->api_key = trim($this->api_key);
  1008. $this->office_phone = trim($this->office_phone);
  1009. $this->office_fax = trim($this->office_fax);
  1010. $this->user_mobile = trim($this->user_mobile);
  1011. $this->email = trim($this->email);
  1012. $this->skype = trim($this->skype);
  1013. $this->job = trim($this->job);
  1014. $this->signature = trim($this->signature);
  1015. $this->note = trim($this->note);
  1016. $this->openid = trim(empty($this->openid)?'':$this->openid); // Avoid warning
  1017. $this->admin = $this->admin?$this->admin:0;
  1018. $this->address = empty($this->address)?'':$this->address;
  1019. $this->zip = empty($this->zip)?'':$this->zip;
  1020. $this->town = empty($this->town)?'':$this->town;
  1021. $this->accountancy_code = trim($this->accountancy_code);
  1022. $this->color = empty($this->color)?'':$this->color;
  1023. // Check parameters
  1024. if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
  1025. {
  1026. $langs->load("errors");
  1027. $this->error = $langs->trans("ErrorBadEMail",$this->email);
  1028. return -1;
  1029. }
  1030. if (empty($this->login))
  1031. {
  1032. $langs->load("errors");
  1033. $this->error = $langs->trans("ErrorFieldRequired",$this->login);
  1034. return -1;
  1035. }
  1036. $this->db->begin();
  1037. // Update datas
  1038. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
  1039. $sql.= " lastname = '".$this->db->escape($this->lastname)."'";
  1040. $sql.= ", firstname = '".$this->db->escape($this->firstname)."'";
  1041. $sql.= ", login = '".$this->db->escape($this->login)."'";
  1042. $sql.= ", api_key = '".$this->db->escape($this->api_key)."'";
  1043. $sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
  1044. $sql.= ", admin = ".$this->admin;
  1045. $sql.= ", address = '".$this->db->escape($this->address)."'";
  1046. $sql.= ", zip = '".$this->db->escape($this->zip)."'";
  1047. $sql.= ", town = '".$this->db->escape($this->town)."'";
  1048. $sql.= ", fk_state = ".((! empty($this->state_id) && $this->state_id > 0)?"'".$this->db->escape($this->state_id)."'":"null");
  1049. $sql.= ", fk_country = ".((! empty($this->country_id) && $this->country_id > 0)?"'".$this->db->escape($this->country_id)."'":"null");
  1050. $sql.= ", office_phone = '".$this->db->escape($this->office_phone)."'";
  1051. $sql.= ", office_fax = '".$this->db->escape($this->office_fax)."'";
  1052. $sql.= ", user_mobile = '".$this->db->escape($this->user_mobile)."'";
  1053. $sql.= ", email = '".$this->db->escape($this->email)."'";
  1054. $sql.= ", skype = '".$this->db->escape($this->skype)."'";
  1055. $sql.= ", job = '".$this->db->escape($this->job)."'";
  1056. $sql.= ", signature = '".$this->db->escape($this->signature)."'";
  1057. $sql.= ", accountancy_code = '".$this->db->escape($this->accountancy_code)."'";
  1058. $sql.= ", color = '".$this->db->escape($this->color)."'";
  1059. $sql.= ", note = '".$this->db->escape($this->note)."'";
  1060. $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null");
  1061. $sql.= ", openid = ".($this->openid?"'".$this->db->escape($this->openid)."'":"null");
  1062. $sql.= ", fk_user = ".($this->fk_user > 0?"'".$this->db->escape($this->fk_user)."'":"null");
  1063. if (isset($this->thm) || $this->thm != '') $sql.= ", thm= ".($this->thm != ''?"'".$this->db->escape($this->thm)."'":"null");
  1064. if (isset($this->tjm) || $this->tjm != '') $sql.= ", tjm= ".($this->tjm != ''?"'".$this->db->escape($this->tjm)."'":"null");
  1065. if (isset($this->salary) || $this->salary != '') $sql.= ", salary= ".($this->salary != ''?"'".$this->db->escape($this->salary)."'":"null");
  1066. if (isset($this->salaryextra) || $this->salaryextra != '') $sql.= ", salaryextra= ".($this->salaryextra != ''?"'".$this->db->escape($this->salaryextra)."'":"null");
  1067. $sql.= ", weeklyhours= ".($this->weeklyhours != ''?"'".$this->db->escape($this->weeklyhours)."'":"null");
  1068. $sql.= ", entity = '".$this->entity."'";
  1069. $sql.= " WHERE rowid = ".$this->id;
  1070. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  1071. $resql = $this->db->query($sql);
  1072. if ($resql)
  1073. {
  1074. $nbrowsaffected+=$this->db->affected_rows($resql);
  1075. // Update password
  1076. if ($this->pass)
  1077. {
  1078. if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted)
  1079. {
  1080. // Si mot de passe saisi et different de celui en base
  1081. $result=$this->setPassword($user,$this->pass,0,$notrigger,$nosyncmemberpass);
  1082. if (! $nbrowsaffected) $nbrowsaffected++;
  1083. }
  1084. }
  1085. // If user is linked to a member, remove old link to this member
  1086. if ($this->fk_member > 0)
  1087. {
  1088. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member;
  1089. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  1090. $resql = $this->db->query($sql);
  1091. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
  1092. }
  1093. // Set link to user
  1094. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member =".($this->fk_member>0?$this->fk_member:'null')." where rowid = ".$this->id;
  1095. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  1096. $resql = $this->db->query($sql);
  1097. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
  1098. if ($nbrowsaffected) // If something has changed in data
  1099. {
  1100. if ($this->fk_member > 0 && ! $nosyncmember)
  1101. {
  1102. require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
  1103. // This user is linked with a member, so we also update members informations
  1104. // if this is an update.
  1105. $adh=new Adherent($this->db);
  1106. $result=$adh->fetch($this->fk_member);
  1107. if ($result >= 0)
  1108. {
  1109. $adh->firstname=$this->firstname;
  1110. $adh->lastname=$this->lastname;
  1111. $adh->login=$this->login;
  1112. $adh->gender=$this->gender;
  1113. $adh->pass=$this->pass;
  1114. $adh->societe=(empty($adh->societe) && $this->societe_id ? $this->societe_id : $adh->societe);
  1115. $adh->email=$this->email;
  1116. $adh->skype=$this->skype;
  1117. $adh->phone=$this->office_phone;
  1118. $adh->phone_mobile=$this->user_mobile;
  1119. $adh->note=$this->note;
  1120. $adh->user_id=$this->id;
  1121. $adh->user_login=$this->login;
  1122. $result=$adh->update($user,0,1);
  1123. if ($result < 0)
  1124. {
  1125. $this->error=$luser->error;
  1126. dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
  1127. $error++;
  1128. }
  1129. }
  1130. else
  1131. {
  1132. $this->error=$adh->error;
  1133. $error++;
  1134. }
  1135. }
  1136. }
  1137. $action='update';
  1138. // Actions on extra fields (by external module or standard code)
  1139. // FIXME le hook fait double emploi avec le trigger !!
  1140. $hookmanager->initHooks(array('userdao'));
  1141. $parameters=array('socid'=>$this->id);
  1142. $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
  1143. if (empty($reshook))
  1144. {
  1145. if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
  1146. {
  1147. $result=$this->insertExtraFields();
  1148. if ($result < 0)
  1149. {
  1150. $error++;
  1151. }
  1152. }
  1153. }
  1154. else if ($reshook < 0) $error++;
  1155. if (! $error && ! $notrigger)
  1156. {
  1157. // Call trigger
  1158. $result=$this->call_trigger('USER_MODIFY',$user);
  1159. if ($result < 0) { $error++; }
  1160. // End call triggers
  1161. }
  1162. if (! $error)
  1163. {
  1164. $this->db->commit();
  1165. return $nbrowsaffected;
  1166. }
  1167. else
  1168. {
  1169. dol_syslog(get_class($this)."::update error=".$this->error,LOG_ERR);
  1170. $this->db->rollback();
  1171. return -1;
  1172. }
  1173. }
  1174. else
  1175. {
  1176. $this->error=$this->db->lasterror();
  1177. $this->db->rollback();
  1178. return -2;
  1179. }
  1180. }
  1181. /**
  1182. * Mise a jour en base de la date de derniere connexion d'un utilisateur
  1183. * Fonction appelee lors d'une nouvelle connexion
  1184. *
  1185. * @return <0 si echec, >=0 si ok
  1186. */
  1187. function update_last_login_date()
  1188. {
  1189. $now=dol_now();
  1190. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
  1191. $sql.= " datepreviouslogin = datelastlogin,";
  1192. $sql.= " datelastlogin = '".$this->db->idate($now)."',";
  1193. $sql.= " tms = tms"; // La date de derniere modif doit changer sauf pour la mise a jour de date de derniere connexion
  1194. $sql.= " WHERE rowid = ".$this->id;
  1195. dol_syslog(get_class($this)."::update_last_login_date user->id=".$this->id." ".$sql, LOG_DEBUG);
  1196. $resql = $this->db->query($sql);
  1197. if ($resql)
  1198. {
  1199. $this->datepreviouslogin=$this->datelastlogin;
  1200. $this->datelastlogin=$now;
  1201. return 1;
  1202. }
  1203. else
  1204. {
  1205. $this->error=$this->db->lasterror().' sql='.$sql;
  1206. return -1;
  1207. }
  1208. }
  1209. /**
  1210. * Change password of a user
  1211. *
  1212. * @param User $user Object user of user making change
  1213. * @param string $password New password in clear text (to generate if not provided)
  1214. * @param int $changelater 1=Change password only after clicking on confirm email
  1215. * @param int $notrigger 1=Does not launch triggers
  1216. * @param int $nosyncmember Do not synchronize linked member
  1217. * @return string If OK return clear password, 0 if no change, < 0 if error
  1218. */
  1219. function setPassword($user, $password='', $changelater=0, $notrigger=0, $nosyncmember=0)
  1220. {
  1221. global $conf, $langs;
  1222. require_once DOL_DOCUMENT_ROOT .'/core/lib/security2.lib.php';
  1223. $error=0;
  1224. dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." changelater=".$changelater." notrigger=".$notrigger." nosyncmember=".$nosyncmember, LOG_DEBUG);
  1225. // If new password not provided, we generate one
  1226. if (! $password)
  1227. {
  1228. $password=getRandomPassword(false);
  1229. }
  1230. // Crypte avec md5
  1231. $password_crypted = dol_hash($password);
  1232. // Mise a jour
  1233. if (! $changelater)
  1234. {
  1235. if (! is_object($this->oldcopy)) $this->oldcopy=dol_clone($this);
  1236. $this->db->begin();
  1237. $sql = "UPDATE ".MAIN_DB_PREFIX."user";
  1238. $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."',";
  1239. $sql.= " pass_temp = null";
  1240. if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
  1241. {
  1242. $sql.= ", pass = null";
  1243. }
  1244. else
  1245. {
  1246. $sql.= ", pass = '".$this->db->escape($password)."'";
  1247. }
  1248. $sql.= " WHERE rowid = ".$this->id;
  1249. dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
  1250. $result = $this->db->query($sql);
  1251. if ($result)
  1252. {
  1253. if ($this->db->affected_rows($result))
  1254. {
  1255. $this->pass=$password;
  1256. $this->pass_indatabase=$password;
  1257. $this->pass_indatabase_crypted=$password_crypted;
  1258. if ($this->fk_member && ! $nosyncmember)
  1259. {
  1260. require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
  1261. // This user is linked with a member, so we also update members informations
  1262. // if this is an update.
  1263. $adh=new Adherent($this->db);
  1264. $result=$adh->fetch($this->fk_member);
  1265. if ($result >= 0)
  1266. {
  1267. $result=$adh->setPassword($user,$this->pass,0,1); // Cryptage non gere dans module adherent
  1268. if ($result < 0)
  1269. {
  1270. $this->error=$adh->error;
  1271. dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR);
  1272. $error++;
  1273. }
  1274. }
  1275. else
  1276. {
  1277. $this->error=$adh->error;
  1278. $error++;
  1279. }
  1280. }
  1281. dol_syslog(get_class($this)."::setPassword notrigger=".$notrigger." error=".$error,LOG_DEBUG);
  1282. if (! $error && ! $notrigger)
  1283. {
  1284. // Call trigger
  1285. $result=$this->call_trigger('USER_NEW_PASSWORD',$user);
  1286. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  1287. // End call triggers
  1288. }
  1289. $this->db->commit();
  1290. return $this->pass;
  1291. }
  1292. else
  1293. {
  1294. $this->db->rollback();
  1295. return 0;
  1296. }
  1297. }
  1298. else
  1299. {
  1300. $this->db->rollback();
  1301. dol_print_error($this->db);
  1302. return -1;
  1303. }
  1304. }
  1305. else
  1306. {
  1307. // We store clear password in password temporary field.
  1308. // After receiving confirmation link, we will crypt it and store it in pass_crypted
  1309. $sql = "UPDATE ".MAIN_DB_PREFIX."user";
  1310. $sql.= " SET pass_temp = '".$this->db->escape($password)."'";
  1311. $sql.= " WHERE rowid = ".$this->id;
  1312. dol_syslog(get_class($this)."::setPassword", LOG_DEBUG); // No log
  1313. $result = $this->db->query($sql);
  1314. if ($result)
  1315. {
  1316. return $password;
  1317. }
  1318. else
  1319. {
  1320. dol_print_error($this->db);
  1321. return -3;
  1322. }
  1323. }
  1324. }
  1325. /**
  1326. * Send new password by email
  1327. *
  1328. * @param User $user Object user that send email
  1329. * @param string $password New password
  1330. * @param int $changelater 1=Change password only after clicking on confirm email
  1331. * @return int < 0 si erreur, > 0 si ok
  1332. */
  1333. function send_password($user, $password='', $changelater=0)
  1334. {
  1335. global $conf,$langs;
  1336. global $dolibarr_main_url_root;
  1337. require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
  1338. $msgishtml=0;
  1339. // Define $msg
  1340. $mesg = '';
  1341. $outputlangs=new Translate("",$conf);
  1342. if (isset($this->conf->MAIN_LANG_DEFAULT)
  1343. && $this->conf->MAIN_LANG_DEFAULT != 'auto')
  1344. { // If user has defined its own language (rare because in most cases, auto is used)
  1345. $outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT);
  1346. }
  1347. else
  1348. { // If user has not defined its own language, we used current language
  1349. $outputlangs=$langs;
  1350. }
  1351. $outputlangs->load("main");
  1352. $outputlangs->load("errors");
  1353. $outputlangs->load("users");
  1354. $outputlangs->load("other");
  1355. $subject = $outputlangs->transnoentitiesnoconv("SubjectNewPassword");
  1356. // Define $urlwithroot
  1357. //$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
  1358. //$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  1359. $urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  1360. if (! $changelater)
  1361. {
  1362. $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived").".\n";
  1363. $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyIs")." :\n\n";
  1364. $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n";
  1365. $mesg.= $outputlangs->transnoentitiesnoconv("Password")." = ".$password."\n\n";
  1366. $mesg.= "\n";
  1367. $url = $urlwithroot.'/';
  1368. $mesg.= $outputlangs->transnoentitiesnoconv("ClickHereToGoTo", $conf->global->MAIN_APPLICATION_TITLE).': '.$url."\n\n";
  1369. $mesg.= "--\n";
  1370. $mesg.= $user->getFullName($outputlangs); // Username that make then sending
  1371. }
  1372. else
  1373. {
  1374. $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived")."\n";
  1375. $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyWillBe")." :\n\n";
  1376. $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n";
  1377. $mesg.= $outputlangs->transnoentitiesnoconv("Password")." = ".$password."\n\n";
  1378. $mesg.= "\n";
  1379. $mesg.= $outputlangs->transnoentitiesnoconv("YouMustClickToChange")." :\n";
  1380. $url = $urlwithroot.'/user/passwordforgotten.php?action=validatenewpassword&username='.$this->login."&passwordhash=".dol_hash($password);
  1381. $mesg.= $url."\n\n";
  1382. $mesg.= $outputlangs->transnoentitiesnoconv("ForgetIfNothing")."\n\n";
  1383. dol_syslog(get_class($this)."::send_password url=".$url);
  1384. }
  1385. $mailfile = new CMailFile(
  1386. $subject,
  1387. $this->email,
  1388. $conf->notification->email_from,
  1389. $mesg,
  1390. array(),
  1391. array(),
  1392. array(),
  1393. '',
  1394. '',
  1395. 0,
  1396. $msgishtml
  1397. );
  1398. if ($mailfile->sendfile())
  1399. {
  1400. return 1;
  1401. }
  1402. else
  1403. {
  1404. $langs->trans("errors");
  1405. $this->error=$langs->trans("ErrorFailedToSendPassword").' '.$mailfile->error;
  1406. return -1;
  1407. }
  1408. }
  1409. /**
  1410. * Renvoie la derniere erreur fonctionnelle de manipulation de l'objet
  1411. *
  1412. * @return string chaine erreur
  1413. */
  1414. function error()
  1415. {
  1416. return $this->error;
  1417. }
  1418. /**
  1419. * Read clicktodial information for user
  1420. *
  1421. * @return <0 if KO, >0 if OK
  1422. */
  1423. function fetch_clicktodial()
  1424. {
  1425. $sql = "SELECT url, login, pass, poste ";
  1426. $sql.= " FROM ".MAIN_DB_PREFIX."user_clicktodial as u";
  1427. $sql.= " WHERE u.fk_user = ".$this->id;
  1428. $resql = $this->db->query($sql);
  1429. if ($resql)
  1430. {
  1431. if ($this->db->num_rows($resql))
  1432. {
  1433. $obj = $this->db->fetch_object($resql);
  1434. $this->clicktodial_url = $obj->url;
  1435. $this->clicktodial_login = $obj->login;
  1436. $this->clicktodial_password = $obj->pass;
  1437. $this->clicktodial_poste = $obj->poste;
  1438. }
  1439. $this->clicktodial_loaded = 1; // Data loaded (found or not)
  1440. $this->db->free($resql);
  1441. return 1;
  1442. }
  1443. else
  1444. {
  1445. $this->error=$this->db->error();
  1446. return -1;
  1447. }
  1448. }
  1449. /**
  1450. * Update clicktodial info
  1451. *
  1452. * @return integer
  1453. */
  1454. function update_clicktodial()
  1455. {
  1456. $this->db->begin();
  1457. $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_clicktodial";
  1458. $sql .= " WHERE fk_user = ".$this->id;
  1459. dol_syslog(get_class($this).'::update_clicktodial', LOG_DEBUG);
  1460. $result = $this->db->query($sql);
  1461. $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_clicktodial";
  1462. $sql .= " (fk_user,url,login,pass,poste)";
  1463. $sql .= " VALUES (".$this->id;
  1464. $sql .= ", '". $this->db->escape($this->clicktodial_url) ."'";
  1465. $sql .= ", '". $this->db->escape($this->clicktodial_login) ."'";
  1466. $sql .= ", '". $this->db->escape($this->clicktodial_password) ."'";
  1467. $sql .= ", '". $this->db->escape($this->clicktodial_poste) ."')";
  1468. dol_syslog(get_class($this).'::update_clicktodial', LOG_DEBUG);
  1469. $result = $this->db->query($sql);
  1470. if ($result)
  1471. {
  1472. $this->db->commit();
  1473. return 1;
  1474. }
  1475. else
  1476. {
  1477. $this->db->rollback();
  1478. $this->error=$this->db->lasterror();
  1479. return -1;
  1480. }
  1481. }
  1482. /**
  1483. * Add user into a group
  1484. *
  1485. * @param int $group Id of group
  1486. * @param int $entity Entity
  1487. * @param int $notrigger Disable triggers
  1488. * @return int <0 if KO, >0 if OK
  1489. */
  1490. function SetInGroup($group, $entity, $notrigger=0)
  1491. {
  1492. global $conf, $langs, $user;
  1493. $error=0;
  1494. $this->db->begin();
  1495. $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user";
  1496. $sql.= " WHERE fk_user = ".$this->id;
  1497. $sql.= " AND fk_usergroup = ".$group;
  1498. $sql.= " AND entity = ".$entity;
  1499. $result = $this->db->query($sql);
  1500. $sql = "INSERT INTO ".MAIN_DB_PREFIX."usergroup_user (entity, fk_user, fk_usergroup)";
  1501. $sql.= " VALUES (".$entity.",".$this->id.",".$group.")";
  1502. $result = $this->db->query($sql);
  1503. if ($result)
  1504. {
  1505. if (! $error && ! $notrigger)
  1506. {
  1507. $this->newgroupid=$group;
  1508. // Call trigger
  1509. $result=$this->call_trigger('USER_SETINGROUP',$user);
  1510. if ($result < 0) { $error++; }
  1511. // End call triggers
  1512. }
  1513. if (! $error)
  1514. {
  1515. $this->db->commit();
  1516. return 1;
  1517. }
  1518. else
  1519. {
  1520. dol_syslog(get_class($this)."::SetInGroup ".$this->error, LOG_ERR);
  1521. $this->db->rollback();
  1522. return -2;
  1523. }
  1524. }
  1525. else
  1526. {
  1527. $this->error=$this->db->lasterror();
  1528. $this->db->rollback();
  1529. return -1;
  1530. }
  1531. }
  1532. /**
  1533. * Remove a user from a group
  1534. *
  1535. * @param int $group Id of group
  1536. * @param int $entity Entity
  1537. * @param int $notrigger Disable triggers
  1538. * @return int <0 if KO, >0 if OK
  1539. */
  1540. function RemoveFromGroup($group, $entity, $notrigger=0)
  1541. {
  1542. global $conf,$langs,$user;
  1543. $error=0;
  1544. $this->db->begin();
  1545. $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user";
  1546. $sql.= " WHERE fk_user = ".$this->id;
  1547. $sql.= " AND fk_usergroup = ".$group;
  1548. $sql.= " AND entity = ".$entity;
  1549. $result = $this->db->query($sql);
  1550. if ($result)
  1551. {
  1552. if (! $error && ! $notrigger)
  1553. {
  1554. $this->oldgroupid=$group;
  1555. // Call trigger
  1556. $result=$this->call_trigger('USER_REMOVEFROMGROUP',$user);
  1557. if ($result < 0) { $error++; }
  1558. // End call triggers
  1559. }
  1560. if (! $error)
  1561. {
  1562. $this->db->commit();
  1563. return 1;
  1564. }
  1565. else
  1566. {
  1567. $this->error=$interface->error;
  1568. dol_syslog(get_class($this)."::RemoveFromGroup ".$this->error, LOG_ERR);
  1569. $this->db->rollback();
  1570. return -2;
  1571. }
  1572. }
  1573. else
  1574. {
  1575. $this->error=$this->db->lasterror();
  1576. $this->db->rollback();
  1577. return -1;
  1578. }
  1579. }
  1580. /**
  1581. * Return a link with photo
  1582. * Use this->id,this->photo
  1583. *
  1584. * @param int $width Width of image
  1585. * @param int $height Height of image
  1586. * @param string $cssclass Force a css class
  1587. * @return string String with URL link
  1588. */
  1589. function getPhotoUrl($width, $height, $cssclass='')
  1590. {
  1591. $result='';
  1592. $result.='<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
  1593. $result.=Form::showphoto('userphoto', $this, $width, $height, 0, $cssclass);
  1594. $result.='</a>';
  1595. return $result;
  1596. }
  1597. /**
  1598. * Return a link to the user card (with optionaly the picto)
  1599. * Use this->id,this->lastname, this->firstname
  1600. *
  1601. * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
  1602. * @param string $option On what the link point to
  1603. * @param integer $infologin Add connection info to the tooltip
  1604. * @param integer $notooltip 1=Disable tooltip
  1605. * @param int $maxlen Max length of visible user name
  1606. * @param int $hidethirdpartylogo Hide logo of thirdparty if user is external user
  1607. * @return string String with URL
  1608. */
  1609. function getNomUrl($withpicto=0, $option='', $infologin=0, $notooltip=0, $maxlen=24, $hidethirdpartylogo=0)
  1610. {
  1611. global $langs, $conf, $db;
  1612. global $dolibarr_main_authentication, $dolibarr_main_demo;
  1613. global $menumanager;
  1614. $result = '';
  1615. $companylink = '';
  1616. $label = '<u>' . $langs->trans("User") . '</u>';
  1617. $label.= '<div width="100%">';
  1618. $label.= '<b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs,'','');
  1619. if (! empty($this->login))
  1620. $label.= '<br><b>' . $langs->trans('Login') . ':</b> ' . $this->login;
  1621. $label.= '<br><b>' . $langs->trans("EMail").':</b> '.$this->email;
  1622. if (! empty($this->admin))
  1623. $label.= '<br><b>' . $langs->trans("Administrator").'</b>: '.yn($this->admin);
  1624. if (! empty($this->societe_id) ) // Add thirdparty for external users
  1625. {
  1626. $thirdpartystatic = new Societe($db);
  1627. $thirdpartystatic->fetch($this->societe_id);
  1628. if (empty($hidethirdpartylogo)) $companylink = ' '.$thirdpartystatic->getNomUrl(2); // picto only of company
  1629. $company=' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')';
  1630. }
  1631. $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal"));
  1632. $label.= '<br><b>' . $langs->trans("Type") . ':</b> ' . $type;
  1633. $label.='</div>';
  1634. if (! empty($this->photo))
  1635. {
  1636. $label.= '<div class="photointooltip">';
  1637. $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip');
  1638. $label.= '</div><div style="clear: both;"></div>';
  1639. }
  1640. // Info Login
  1641. if ($infologin)
  1642. {
  1643. $label.= '<br>';
  1644. $label.= '<br><u>'.$langs->trans("Connection").'</u>';
  1645. $label.= '<br><b>'.$langs->trans("IPAddress").'</b>: '.$_SERVER["REMOTE_ADDR"];
  1646. if (! empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $label.= '<br><b>'.$langs->trans("ConnectedOnMultiCompany").':</b> '.$conf->entity.' (user entity '.$this->entity.')';
  1647. $label.= '<br><b>'.$langs->trans("AuthenticationMode").':</b> '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo)?'':' (demo)');
  1648. $label.= '<br><b>'.$langs->trans("ConnectedSince").':</b> '.dol_print_date($this->datelastlogin,"dayhour");
  1649. $label.= '<br><b>'.$langs->trans("PreviousConnexion").':</b> '.dol_print_date($this->datepreviouslogin,"dayhour");
  1650. $label.= '<br><b>'.$langs->trans("CurrentTheme").':</b> '.$conf->theme;
  1651. $label.= '<br><b>'.$langs->trans("CurrentMenuManager").':</b> '.$menumanager->name;
  1652. $s=picto_from_langcode($langs->getDefaultLang());
  1653. $label.= '<br><b>'.$langs->trans("CurrentUserLanguage").':</b> '.($s?$s.' ':'').$langs->getDefaultLang();
  1654. $label.= '<br><b>'.$langs->trans("Browser").':</b> '.$conf->browser->name.($conf->browser->version?' '.$conf->browser->version:'').' ('.$_SERVER['HTTP_USER_AGENT'].')';
  1655. if (! empty($conf->browser->phone)) $label.= '<br><b>'.$langs->trans("Phone").':</b> '.$conf->browser->phone;
  1656. if (! empty($_SESSION["disablemodules"])) $label.= '<br><b>'.$langs->trans("DisabledModules").':</b> <br>'.join(', ',explode(',',$_SESSION["disablemodules"]));
  1657. }
  1658. $link = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'"';
  1659. $link.= ($notooltip?'':' title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip"');
  1660. $link.= '>';
  1661. $linkend='</a>';
  1662. if ($withpicto)
  1663. {
  1664. $result.=($link.img_object(($notooltip?'':$label), 'user', ($notooltip?'':'class="classfortooltip"')).$linkend);
  1665. if ($withpicto != 2) $result.=' ';
  1666. }
  1667. $result.= $link . $this->getFullName($langs,'',-1,$maxlen) . $linkend . $companylink;
  1668. return $result;
  1669. }
  1670. /**
  1671. * Renvoie login clicable (avec eventuellement le picto)
  1672. *
  1673. * @param int $withpicto Include picto into link
  1674. * @param string $option Sur quoi pointe le lien
  1675. * @return string Chaine avec URL
  1676. */
  1677. function getLoginUrl($withpicto=0,$option='')
  1678. {
  1679. global $langs;
  1680. $result='';
  1681. $link = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
  1682. $linkend='</a>';
  1683. if ($option == 'xxx')
  1684. {
  1685. $link = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
  1686. $linkend='</a>';
  1687. }
  1688. if ($withpicto) $result.=($link.img_object($langs->trans("ShowUser"),'user').$linkend.' ');
  1689. $result.=$link.$this->login.$linkend;
  1690. return $result;
  1691. }
  1692. /**
  1693. * Retourne le libelle du statut d'un user (actif, inactif)
  1694. *
  1695. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  1696. * @return string Label of status
  1697. */
  1698. function getLibStatut($mode=0)
  1699. {
  1700. return $this->LibStatut($this->statut,$mode);
  1701. }
  1702. /**
  1703. * Renvoi le libelle d'un statut donne
  1704. *
  1705. * @param int $statut Id statut
  1706. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  1707. * @return string Label of status
  1708. */
  1709. function LibStatut($statut,$mode=0)
  1710. {
  1711. global $langs;
  1712. $langs->load('users');
  1713. if ($mode == 0)
  1714. {
  1715. $prefix='';
  1716. if ($statut == 1) return $langs->trans('Enabled');
  1717. if ($statut == 0) return $langs->trans('Disabled');
  1718. }
  1719. if ($mode == 1)
  1720. {
  1721. if ($statut == 1) return $langs->trans('Enabled');
  1722. if ($statut == 0) return $langs->trans('Disabled');
  1723. }
  1724. if ($mode == 2)
  1725. {
  1726. if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
  1727. if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
  1728. }
  1729. if ($mode == 3)
  1730. {
  1731. if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4');
  1732. if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5');
  1733. }
  1734. if ($mode == 4)
  1735. {
  1736. if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
  1737. if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
  1738. }
  1739. if ($mode == 5)
  1740. {
  1741. if ($statut == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
  1742. if ($statut == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
  1743. }
  1744. }
  1745. /**
  1746. * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
  1747. *
  1748. * @param array $info Info array loaded by _load_ldap_info
  1749. * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
  1750. * 1=
  1751. * 2=Return key only (uid=qqq)
  1752. * @return string DN
  1753. */
  1754. function _load_ldap_dn($info,$mode=0)
  1755. {
  1756. global $conf;
  1757. $dn='';
  1758. if ($mode==0) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS].",".$conf->global->LDAP_USER_DN;
  1759. if ($mode==1) $dn=$conf->global->LDAP_USER_DN;
  1760. if ($mode==2) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS];
  1761. return $dn;
  1762. }
  1763. /**
  1764. * Initialize the info array (array of LDAP values) that will be used to call LDAP functions
  1765. *
  1766. * @return array Tableau info des attributs
  1767. */
  1768. function _load_ldap_info()
  1769. {
  1770. global $conf,$langs;
  1771. $info=array();
  1772. // Object classes
  1773. $info["objectclass"]=explode(',',$conf->global->LDAP_USER_OBJECT_CLASS);
  1774. $this->fullname=$this->getFullName($langs);
  1775. // Champs
  1776. if ($this->fullname && ! empty($conf->global->LDAP_FIELD_FULLNAME)) $info[$conf->global->LDAP_FIELD_FULLNAME] = $this->fullname;
  1777. if ($this->lastname && ! empty($conf->global->LDAP_FIELD_NAME)) $info[$conf->global->LDAP_FIELD_NAME] = $this->lastname;
  1778. if ($this->firstname && ! empty($conf->global->LDAP_FIELD_FIRSTNAME)) $info[$conf->global->LDAP_FIELD_FIRSTNAME] = $this->firstname;
  1779. if ($this->login && ! empty($conf->global->LDAP_FIELD_LOGIN)) $info[$conf->global->LDAP_FIELD_LOGIN] = $this->login;
  1780. if ($this->login && ! empty($conf->global->LDAP_FIELD_LOGIN_SAMBA)) $info[$conf->global->LDAP_FIELD_LOGIN_SAMBA] = $this->login;
  1781. if ($this->pass && ! empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte
  1782. if ($this->ldap_sid && ! empty($conf->global->LDAP_FIELD_SID)) $info[$conf->global->LDAP_FIELD_SID] = $this->ldap_sid;
  1783. if ($this->societe_id > 0)
  1784. {
  1785. $soc = new Societe($this->db);
  1786. $soc->fetch($this->societe_id);
  1787. $info["o"] = $soc->lastname;
  1788. if ($soc->client == 1) $info["businessCategory"] = "Customers";
  1789. if ($soc->client == 2) $info["businessCategory"] = "Prospects";
  1790. if ($soc->fournisseur == 1) $info["businessCategory"] = "Suppliers";
  1791. }
  1792. if ($this->address && ! empty($conf->global->LDAP_FIELD_ADDRESS)) $info[$conf->global->LDAP_FIELD_ADDRESS] = $this->address;
  1793. if ($this->zip && ! empty($conf->global->LDAP_FIELD_ZIP)) $info[$conf->global->LDAP_FIELD_ZIP] = $this->zip;
  1794. if ($this->town && ! empty($conf->global->LDAP_FIELD_TOWN)) $info[$conf->global->LDAP_FIELD_TOWN] = $this->town;
  1795. if ($this->office_phone && ! empty($conf->global->LDAP_FIELD_PHONE)) $info[$conf->global->LDAP_FIELD_PHONE] = $this->office_phone;
  1796. if ($this->user_mobile && ! empty($conf->global->LDAP_FIELD_MOBILE)) $info[$conf->global->LDAP_FIELD_MOBILE] = $this->user_mobile;
  1797. if ($this->office_fax && ! empty($conf->global->LDAP_FIELD_FAX)) $info[$conf->global->LDAP_FIELD_FAX] = $this->office_fax;
  1798. if ($this->note && ! empty($conf->global->LDAP_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_FIELD_DESCRIPTION] = $this->note;
  1799. if ($this->email && ! empty($conf->global->LDAP_FIELD_MAIL)) $info[$conf->global->LDAP_FIELD_MAIL] = $this->email;
  1800. if ($this->skype && ! empty($conf->global->LDAP_FIELD_SKYPE)) $info[$conf->global->LDAP_FIELD_SKYPE] = $this->skype;
  1801. if ($conf->global->LDAP_SERVER_TYPE == 'egroupware')
  1802. {
  1803. $info["objectclass"][4] = "phpgwContact"; // compatibilite egroupware
  1804. $info['uidnumber'] = $this->id;
  1805. $info['phpgwTz'] = 0;
  1806. $info['phpgwMailType'] = 'INTERNET';
  1807. $info['phpgwMailHomeType'] = 'INTERNET';
  1808. $info["phpgwContactTypeId"] = 'n';
  1809. $info["phpgwContactCatId"] = 0;
  1810. $info["phpgwContactAccess"] = "public";
  1811. if (dol_strlen($this->egroupware_id) == 0)
  1812. {
  1813. $this->egroupware_id = 1;
  1814. }
  1815. $info["phpgwContactOwner"] = $this->egroupware_id;
  1816. if ($this->email) $info["rfc822Mailbox"] = $this->email;
  1817. if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile;
  1818. }
  1819. return $info;
  1820. }
  1821. /**
  1822. * Initialise an instance with random values.
  1823. * Used to build previews or test instances.
  1824. * id must be 0 if object instance is a specimen.
  1825. *
  1826. * @return void
  1827. */
  1828. function initAsSpecimen()
  1829. {
  1830. global $user,$langs;
  1831. $now=dol_now();
  1832. // Initialise parametres
  1833. $this->id=0;
  1834. $this->ref = 'SPECIMEN';
  1835. $this->specimen=1;
  1836. $this->lastname='DOLIBARR';
  1837. $this->firstname='SPECIMEN';
  1838. $this->gender='man';
  1839. $this->note='This is a note';
  1840. $this->email='email@specimen.com';
  1841. $this->skype='tom.hanson';
  1842. $this->office_phone='0999999999';
  1843. $this->office_fax='0999999998';
  1844. $this->user_mobile='0999999997';
  1845. $this->admin=0;
  1846. $this->login='dolibspec';
  1847. $this->pass='dolibspec';
  1848. //$this->pass_indatabase='dolibspec'; Set after a fetch
  1849. //$this->pass_indatabase_crypted='e80ca5a88c892b0aaaf7e154853bccab'; Set after a fetch
  1850. $this->datec=$now;
  1851. $this->datem=$now;
  1852. $this->datelastlogin=$now;
  1853. $this->datepreviouslogin=$now;
  1854. $this->statut=1;
  1855. //$this->societe_id = 1; For external users
  1856. //$this->contact_id = 1; For external users
  1857. $this->entity = 1;
  1858. }
  1859. /**
  1860. * Load info of user object
  1861. *
  1862. * @param int $id Id of user to load
  1863. * @return void
  1864. */
  1865. function info($id)
  1866. {
  1867. $sql = "SELECT u.rowid, u.login as ref, u.datec,";
  1868. $sql.= " u.tms as date_modification, u.entity";
  1869. $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
  1870. $sql.= " WHERE u.rowid = ".$id;
  1871. $result=$this->db->query($sql);
  1872. if ($result)
  1873. {
  1874. if ($this->db->num_rows($result))
  1875. {
  1876. $obj = $this->db->fetch_object($result);
  1877. $this->id = $obj->rowid;
  1878. $this->ref = (! $obj->ref) ? $obj->rowid : $obj->ref;
  1879. $this->date_creation = $this->db->jdate($obj->datec);
  1880. $this->date_modification = $this->db->jdate($obj->date_modification);
  1881. $this->entity = $obj->entity;
  1882. }
  1883. $this->db->free($result);
  1884. }
  1885. else
  1886. {
  1887. dol_print_error($this->db);
  1888. }
  1889. }
  1890. /**
  1891. * Return number of mass Emailing received by this contacts with its email
  1892. *
  1893. * @return int Number of EMailings
  1894. */
  1895. function getNbOfEMailings()
  1896. {
  1897. $sql = "SELECT count(mc.email) as nb";
  1898. $sql.= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
  1899. $sql.= " WHERE mc.email = '".$this->db->escape($this->email)."'";
  1900. $sql.= " AND mc.statut=1"; // -1 erreur, 0 non envoye, 1 envoye avec succes
  1901. $resql=$this->db->query($sql);
  1902. if ($resql)
  1903. {
  1904. $obj = $this->db->fetch_object($resql);
  1905. $nb=$obj->nb;
  1906. $this->db->free($resql);
  1907. return $nb;
  1908. }
  1909. else
  1910. {
  1911. $this->error=$this->db->error();
  1912. return -1;
  1913. }
  1914. }
  1915. /**
  1916. * Return number of existing users
  1917. *
  1918. * @param string $limitTo Limit to 'active' or 'superadmin' users
  1919. * @param bool $all Return for all entities
  1920. * @return int Number of users
  1921. */
  1922. function getNbOfUsers($limitTo='active', $all=false)
  1923. {
  1924. global $conf;
  1925. $sql = "SELECT count(rowid) as nb";
  1926. $sql.= " FROM ".MAIN_DB_PREFIX."user";
  1927. if ($limitTo == 'superadmin')
  1928. {
  1929. $sql.= " WHERE entity = 0";
  1930. }
  1931. else
  1932. {
  1933. if ($all) $sql.= " WHERE entity > 0"; // all users except superadmins
  1934. else $sql.= " WHERE entity = ".$conf->entity;
  1935. if ($limitTo == 'active') $sql.= " AND statut = 1";
  1936. }
  1937. $resql=$this->db->query($sql);
  1938. if ($resql)
  1939. {
  1940. $obj = $this->db->fetch_object($resql);
  1941. $nb=$obj->nb;
  1942. $this->db->free($resql);
  1943. return $nb;
  1944. }
  1945. else
  1946. {
  1947. $this->error=$this->db->error();
  1948. return -1;
  1949. }
  1950. }
  1951. /**
  1952. * Update user using data from the LDAP
  1953. *
  1954. * @param ldapuser $ldapuser Ladp User
  1955. *
  1956. * @return int <0 if KO, >0 if OK
  1957. */
  1958. function update_ldap2dolibarr(&$ldapuser)
  1959. {
  1960. // TODO: Voir pourquoi le update met à jour avec toutes les valeurs vide (global $user écrase ?)
  1961. global $user, $conf;
  1962. $this->firstname=$ldapuser->{$conf->global->LDAP_FIELD_FIRSTNAME};
  1963. $this->lastname=$ldapuser->{$conf->global->LDAP_FIELD_NAME};
  1964. $this->login=$ldapuser->{$conf->global->LDAP_FIELD_LOGIN};
  1965. $this->pass=$ldapuser->{$conf->global->LDAP_FIELD_PASSWORD};
  1966. $this->pass_indatabase_crypted=$ldapuser->{$conf->global->LDAP_FIELD_PASSWORD_CRYPTED};
  1967. $this->office_phone=$ldapuser->{$conf->global->LDAP_FIELD_PHONE};
  1968. $this->user_mobile=$ldapuser->{$conf->global->LDAP_FIELD_MOBILE};
  1969. $this->office_fax=$ldapuser->{$conf->global->LDAP_FIELD_FAX};
  1970. $this->email=$ldapuser->{$conf->global->LDAP_FIELD_MAIL};
  1971. $this->skype=$ldapuser->{$conf->global->LDAP_FIELD_SKYPE};
  1972. $this->ldap_sid=$ldapuser->{$conf->global->LDAP_FIELD_SID};
  1973. $this->job=$ldapuser->{$conf->global->LDAP_FIELD_TITLE};
  1974. $this->note=$ldapuser->{$conf->global->LDAP_FIELD_DESCRIPTION};
  1975. $result = $this->update($user);
  1976. dol_syslog(get_class($this)."::update_ldap2dolibarr result=".$result, LOG_DEBUG);
  1977. return $result;
  1978. }
  1979. /**
  1980. * Return and array with all instanciated first level children users of current user
  1981. *
  1982. * @return void
  1983. */
  1984. function get_children()
  1985. {
  1986. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."user";
  1987. $sql.= " WHERE fk_user = ".$this->id;
  1988. dol_syslog(get_class($this)."::get_children result=".$result, LOG_DEBUG);
  1989. $res = $this->db->query($sql);
  1990. if ($res)
  1991. {
  1992. $users = array ();
  1993. while ($rec = $this->db->fetch_array($res))
  1994. {
  1995. $user = new User($this->db);
  1996. $user->fetch($rec['rowid']);
  1997. $users[] = $user;
  1998. }
  1999. return $users;
  2000. }
  2001. else
  2002. {
  2003. dol_print_error($this->db);
  2004. return -1;
  2005. }
  2006. }
  2007. /**
  2008. * Load this->parentof that is array(id_son=>id_parent, ...)
  2009. *
  2010. * @return int <0 if KO, >0 if OK
  2011. */
  2012. private function load_parentof()
  2013. {
  2014. global $conf;
  2015. $this->parentof=array();
  2016. // Load array[child]=parent
  2017. $sql = "SELECT fk_user as id_parent, rowid as id_son";
  2018. $sql.= " FROM ".MAIN_DB_PREFIX."user";
  2019. $sql.= " WHERE fk_user <> 0";
  2020. $sql.= " AND entity IN (".getEntity('user',1).")";
  2021. dol_syslog(get_class($this)."::load_parentof", LOG_DEBUG);
  2022. $resql = $this->db->query($sql);
  2023. if ($resql)
  2024. {
  2025. while ($obj= $this->db->fetch_object($resql))
  2026. {
  2027. $this->parentof[$obj->id_son]=$obj->id_parent;
  2028. }
  2029. return 1;
  2030. }
  2031. else
  2032. {
  2033. dol_print_error($this->db);
  2034. return -1;
  2035. }
  2036. }
  2037. /**
  2038. * Reconstruit l'arborescence hierarchique des users sous la forme d'un tableau
  2039. * Set and return this->users that is an array sorted according to tree with arrays of:
  2040. * id = id user
  2041. * lastname
  2042. * firstname
  2043. * fullname = nom avec chemin complet du user
  2044. * fullpath = chemin complet compose des id: "_grandparentid_parentid_id"
  2045. *
  2046. * @param int $deleteafterid Removed all users including the leaf $deleteafterid (and all its child) in user tree.
  2047. * @param string $filter SQL filter on users
  2048. * @return array Array of users $this->users. Note: $this->parentof is also set.
  2049. */
  2050. function get_full_tree($deleteafterid=0, $filter='')
  2051. {
  2052. global $conf,$user;
  2053. $this->users = array();
  2054. // Init this->parentof that is array(id_son=>id_parent, ...)
  2055. $this->load_parentof();
  2056. // Init $this->users array
  2057. $sql = "SELECT DISTINCT u.rowid, u.firstname, u.lastname, u.fk_user, u.fk_soc, u.login, u.email, u.gender, u.statut, u.entity"; // Distinct reduce pb with old tables with duplicates
  2058. $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
  2059. if(! empty($conf->multicompany->enabled) && $conf->entity == 1 && (! empty($conf->multicompany->transverse_mode) || (! empty($user->admin) && empty($user->entity))))
  2060. {
  2061. $sql.= " WHERE u.entity IS NOT NULL";
  2062. }
  2063. else
  2064. {
  2065. $sql.= " WHERE u.entity IN (".getEntity('user',1).")";
  2066. }
  2067. if ($filter) $sql.=" AND ".$filter;
  2068. dol_syslog(get_class($this)."::get_full_tree get user list", LOG_DEBUG);
  2069. $resql = $this->db->query($sql);
  2070. if ($resql)
  2071. {
  2072. $i=0;
  2073. while ($obj = $this->db->fetch_object($resql))
  2074. {
  2075. $this->users[$obj->rowid]['rowid'] = $obj->rowid;
  2076. $this->users[$obj->rowid]['id'] = $obj->rowid;
  2077. $this->users[$obj->rowid]['fk_user'] = $obj->fk_user;
  2078. $this->users[$obj->rowid]['fk_soc'] = $obj->fk_soc;
  2079. $this->users[$obj->rowid]['firstname'] = $obj->firstname;
  2080. $this->users[$obj->rowid]['lastname'] = $obj->lastname;
  2081. $this->users[$obj->rowid]['login'] = $obj->login;
  2082. $this->users[$obj->rowid]['statut'] = $obj->statut;
  2083. $this->users[$obj->rowid]['entity'] = $obj->entity;
  2084. $this->users[$obj->rowid]['email'] = $obj->email;
  2085. $this->users[$obj->rowid]['gender'] = $obj->gender;
  2086. $i++;
  2087. }
  2088. }
  2089. else
  2090. {
  2091. dol_print_error($this->db);
  2092. return -1;
  2093. }
  2094. // We add the fullpath property to each elements of first level (no parent exists)
  2095. dol_syslog(get_class($this)."::get_full_tree call to build_path_from_id_user", LOG_DEBUG);
  2096. foreach($this->users as $key => $val)
  2097. {
  2098. $this->build_path_from_id_user($key,0); // Process a branch from the root user key (this user has no parent)
  2099. }
  2100. // Exclude leaf including $deleteafterid from tree
  2101. if ($deleteafterid)
  2102. {
  2103. //print "Look to discard user ".$deleteafterid."\n";
  2104. $keyfilter1='^'.$deleteafterid.'$';
  2105. $keyfilter2='_'.$deleteafterid.'$';
  2106. $keyfilter3='^'.$deleteafterid.'_';
  2107. $keyfilter4='_'.$deleteafterid.'_';
  2108. foreach($this->users as $key => $val)
  2109. {
  2110. if (preg_match('/'.$keyfilter1.'/',$val['fullpath']) || preg_match('/'.$keyfilter2.'/',$val['fullpath'])
  2111. || preg_match('/'.$keyfilter3.'/',$val['fullpath']) || preg_match('/'.$keyfilter4.'/',$val['fullpath']))
  2112. {
  2113. unset($this->users[$key]);
  2114. }
  2115. }
  2116. }
  2117. dol_syslog(get_class($this)."::get_full_tree dol_sort_array", LOG_DEBUG);
  2118. $this->users=dol_sort_array($this->users, 'fullname', 'asc', true, false);
  2119. //var_dump($this->users);
  2120. return $this->users;
  2121. }
  2122. /**
  2123. * Return list of all child users id in herarchy (all sublevels).
  2124. *
  2125. * @return array Array of user id lower than user. This overwrite this->users.
  2126. */
  2127. function getAllChildIds()
  2128. {
  2129. // Init this->users
  2130. $this->get_full_tree();
  2131. $idtoscan=$this->id;
  2132. $childids=array();
  2133. dol_syslog("Build childid for id = ".$idtoscan);
  2134. foreach($this->users as $id => $val)
  2135. {
  2136. //var_dump($val['fullpath']);
  2137. if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id'];
  2138. }
  2139. return $childids;
  2140. }
  2141. /**
  2142. * For user id_user and its childs available in this->users, define property fullpath and fullname
  2143. *
  2144. * @param int $id_user id_user entry to update
  2145. * @param int $protection Deep counter to avoid infinite loop
  2146. * @return void
  2147. */
  2148. function build_path_from_id_user($id_user,$protection=1000)
  2149. {
  2150. dol_syslog(get_class($this)."::build_path_from_id_user id_user=".$id_user." protection=".$protection, LOG_DEBUG);
  2151. if (! empty($this->users[$id_user]['fullpath']))
  2152. {
  2153. // Already defined
  2154. dol_syslog(get_class($this)."::build_path_from_id_user fullpath and fullname already defined", LOG_WARNING);
  2155. return;
  2156. }
  2157. // Define fullpath and fullname
  2158. $this->users[$id_user]['fullpath'] = '_'.$id_user;
  2159. $this->users[$id_user]['fullname'] = $this->users[$id_user]['lastname'];
  2160. $i=0; $cursor_user=$id_user;
  2161. while ((empty($protection) || $i < $protection) && ! empty($this->parentof[$cursor_user]))
  2162. {
  2163. $this->users[$id_user]['fullpath'] = '_'.$this->parentof[$cursor_user].$this->users[$id_user]['fullpath'];
  2164. $this->users[$id_user]['fullname'] = $this->users[$this->parentof[$cursor_user]]['lastname'].' >> '.$this->users[$id_user]['fullname'];
  2165. $i++; $cursor_user=$this->parentof[$cursor_user];
  2166. }
  2167. // We count number of _ to have level
  2168. $this->users[$id_user]['level']=dol_strlen(preg_replace('/[^_]/i','',$this->users[$id_user]['fullpath']));
  2169. return;
  2170. }
  2171. /**
  2172. * Function used to replace a thirdparty id with another one.
  2173. *
  2174. * @param DoliDB $db Database handler
  2175. * @param int $origin_id Old thirdparty id
  2176. * @param int $dest_id New thirdparty id
  2177. * @return bool
  2178. */
  2179. public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
  2180. {
  2181. $tables = array(
  2182. 'user'
  2183. );
  2184. return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
  2185. }
  2186. }