user.class.php 82 KB

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