dolibarr  7.0.0-beta
user.class.php
Go to the documentation of this file.
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-2017 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 
34 require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
35 
39 class User extends CommonObject
40 {
41  public $element='user';
42  public $table_element='user';
43  public $fk_element='fk_user';
44  public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
45 
46  public $id=0;
47  public $statut;
48  public $ldap_sid;
49  public $search_sid;
50  public $employee;
51  public $gender;
52  public $birth;
53  public $email;
54  public $skype;
55  public $job;
56  public $signature;
57  public $address;
58  public $zip;
59  public $town;
60  public $state_id; // The state/department
61  public $state_code;
62  public $state;
63  public $office_phone;
64  public $office_fax;
65  public $user_mobile;
66  public $admin;
67  public $login;
68  public $api_key;
69  public $entity;
70 
72  public $pass;
77 
78  public $datec;
79  public $datem;
80 
82 
86  public $societe_id;
91  public $contact_id;
92  public $socid;
93  public $contactid;
94 
95  public $fk_member;
96  public $fk_user;
97 
98  public $clicktodial_url;
99  public $clicktodial_login;
100  public $clicktodial_password;
101  public $clicktodial_poste;
102 
103  public $datelastlogin;
104  public $datepreviouslogin;
105  public $photo;
106  public $lang;
107 
108  public $rights; // Array of permissions user->rights->permx
109  public $all_permissions_are_loaded; // All permission are loaded
110  public $nb_rights; // Number of rights granted to the user
111  private $_tab_loaded=array(); // Cache array of already loaded permissions
112 
113  public $conf; // To store personal config
114  public $default_values; // To store default values for user
115  public $lastsearch_values_tmp; // To store current search criterias for user
116  public $lastsearch_values; // To store last saved search criterias for user
117 
118  public $users; // To store all tree of users hierarchy
119  public $parentof; // To store an array of all parents for all ids.
120  private $cache_childids;
121 
122  public $accountancy_code; // Accountancy code in prevision of the complete accountancy module
123 
124  public $thm; // Average cost of employee - Used for valuation of time spent
125  public $tjm; // Average cost of employee
126 
127  public $salary; // Monthly salary - Denormalized value from llx_user_employment
128  public $salaryextra; // Monthly salary extra - Denormalized value from llx_user_employment
129  public $weeklyhours; // Weekly hours - Denormalized value from llx_user_employment
130 
131  public $color; // Define background color for user in agenda
132 
133  public $dateemployment; // Define date of employment by company
134 
135  public $default_c_exp_tax_cat;
136  public $default_range;
137 
143  function __construct($db)
144  {
145  $this->db = $db;
146 
147  // User preference
148  $this->liste_limit = 0;
149  $this->clicktodial_loaded = 0;
150 
151  // For cache usage
152  $this->all_permissions_are_loaded = 0;
153  $this->nb_rights = 0;
154 
155  // Force some default values
156  $this->admin = 0;
157  $this->employee = 1;
158 
159  $this->conf = new stdClass();
160  $this->rights = new stdClass();
161  $this->rights->user = new stdClass();
162  $this->rights->user->user = new stdClass();
163  $this->rights->user->self = new stdClass();
164  }
165 
177  function fetch($id='', $login='', $sid='', $loadpersonalconf=0, $entity=-1)
178  {
179  global $conf, $user;
180 
181  // Clean parameters
182  $login=trim($login);
183 
184  // Get user
185  $sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.signature, u.office_phone, u.office_fax, u.user_mobile,";
186  $sql.= " u.address, u.zip, u.town, u.fk_state as state_id, u.fk_country as country_id,";
187  $sql.= " u.admin, u.login, u.note,";
188  $sql.= " u.pass, u.pass_crypted, u.pass_temp, u.api_key,";
189  $sql.= " u.fk_soc, u.fk_socpeople, u.fk_member, u.fk_user, u.ldap_sid,";
190  $sql.= " u.statut, u.lang, u.entity,";
191  $sql.= " u.datec as datec,";
192  $sql.= " u.tms as datem,";
193  $sql.= " u.datelastlogin as datel,";
194  $sql.= " u.datepreviouslogin as datep,";
195  $sql.= " u.photo as photo,";
196  $sql.= " u.openid as openid,";
197  $sql.= " u.accountancy_code,";
198  $sql.= " u.thm,";
199  $sql.= " u.tjm,";
200  $sql.= " u.salary,";
201  $sql.= " u.salaryextra,";
202  $sql.= " u.weeklyhours,";
203  $sql.= " u.color,";
204  $sql.= " u.dateemployment,";
205  $sql.= " u.ref_int, u.ref_ext,";
206  $sql.= " u.default_range, u.default_c_exp_tax_cat,"; // Expense report default mode
207  $sql.= " c.code as country_code, c.label as country,";
208  $sql.= " d.code_departement as state_code, d.nom as state";
209  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
210  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON u.fk_country = c.rowid";
211  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON u.fk_state = d.rowid";
212 
213  if ($entity < 0)
214  {
215  if ((empty($conf->multicompany->enabled) || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) && (! empty($user->entity)))
216  {
217  $sql.= " WHERE u.entity IN (0,".$conf->entity.")";
218  }
219  else
220  {
221  $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
222  }
223  }
224  else // The fetch was forced on an entity
225  {
226  if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
227  $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
228  else
229  $sql.= " WHERE u.entity IN (0, ".(($entity!='' && $entity >= 0)?$entity:$conf->entity).")"; // search in entity provided in parameter
230  }
231 
232  if ($sid) // permet une recherche du user par son SID ActiveDirectory ou Samba
233  {
234  $sql.= " AND (u.ldap_sid = '".$this->db->escape($sid)."' OR u.login = '".$this->db->escape($login)."') LIMIT 1";
235  }
236  else if ($login)
237  {
238  $sql.= " AND u.login = '".$this->db->escape($login)."'";
239  }
240  else
241  {
242  $sql.= " AND u.rowid = ".$id;
243  }
244  $sql.= " ORDER BY u.entity ASC"; // Avoid random result when there is 2 login in 2 different entities
245 
246  $result = $this->db->query($sql);
247  if ($result)
248  {
249  $obj = $this->db->fetch_object($result);
250  if ($obj)
251  {
252  $this->id = $obj->rowid;
253  $this->ref = $obj->rowid;
254 
255  $this->ref_int = $obj->ref_int;
256  $this->ref_ext = $obj->ref_ext;
257 
258  $this->ldap_sid = $obj->ldap_sid;
259  $this->lastname = $obj->lastname;
260  $this->firstname = $obj->firstname;
261 
262  $this->employee = $obj->employee;
263 
264  $this->login = $obj->login;
265  $this->gender = $obj->gender;
266  $this->birth = $this->db->jdate($obj->birth);
267  $this->pass_indatabase = $obj->pass;
268  $this->pass_indatabase_crypted = $obj->pass_crypted;
269  $this->pass = $obj->pass;
270  $this->pass_temp = $obj->pass_temp;
271  $this->api_key = $obj->api_key;
272 
273  $this->address = $obj->address;
274  $this->zip = $obj->zip;
275  $this->town = $obj->town;
276 
277  $this->country_id = $obj->country_id;
278  $this->country_code = $obj->country_id?$obj->country_code:'';
279  //$this->country = $obj->country_id?($langs->trans('Country'.$obj->country_code)!='Country'.$obj->country_code?$langs->transnoentities('Country'.$obj->country_code):$obj->country):'';
280 
281  $this->state_id = $obj->state_id;
282  $this->state_code = $obj->state_code;
283  $this->state = ($obj->state!='-'?$obj->state:'');
284 
285  $this->office_phone = $obj->office_phone;
286  $this->office_fax = $obj->office_fax;
287  $this->user_mobile = $obj->user_mobile;
288  $this->email = $obj->email;
289  $this->skype = $obj->skype;
290  $this->job = $obj->job;
291  $this->signature = $obj->signature;
292  $this->admin = $obj->admin;
293  $this->note = $obj->note;
294  $this->statut = $obj->statut;
295  $this->photo = $obj->photo;
296  $this->openid = $obj->openid;
297  $this->lang = $obj->lang;
298  $this->entity = $obj->entity;
299  $this->accountancy_code = $obj->accountancy_code;
300  $this->thm = $obj->thm;
301  $this->tjm = $obj->tjm;
302  $this->salary = $obj->salary;
303  $this->salaryextra = $obj->salaryextra;
304  $this->weeklyhours = $obj->weeklyhours;
305  $this->color = $obj->color;
306  $this->dateemployment = $this->db->jdate($obj->dateemployment);
307 
308  $this->datec = $this->db->jdate($obj->datec);
309  $this->datem = $this->db->jdate($obj->datem);
310  $this->datelastlogin = $this->db->jdate($obj->datel);
311  $this->datepreviouslogin = $this->db->jdate($obj->datep);
312 
313  $this->societe_id = $obj->fk_soc; // deprecated
314  $this->contact_id = $obj->fk_socpeople; // deprecated
315  $this->socid = $obj->fk_soc;
316  $this->contactid = $obj->fk_socpeople;
317  $this->fk_member = $obj->fk_member;
318  $this->fk_user = $obj->fk_user;
319 
320  $this->default_range = $obj->default_range;
321  $this->default_c_exp_tax_cat = $obj->default_c_exp_tax_cat;
322 
323  // Protection when module multicompany was set, admin was set to first entity and then, the module was disabled,
324  // in such case, this admin user must be admin for ALL entities.
325  if (empty($conf->multicompany->enabled) && $this->admin && $this->entity == 1) $this->entity = 0;
326 
327  // Retreive all extrafield for thirdparty
328  // fetch optionals attributes and labels
329  require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
330  $extrafields=new ExtraFields($this->db);
331  $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true);
332  $this->fetch_optionals($this->id,$extralabels);
333 
334  $this->db->free($result);
335  }
336  else
337  {
338  $this->error="USERNOTFOUND";
339  dol_syslog(get_class($this)."::fetch user not found", LOG_DEBUG);
340 
341  $this->db->free($result);
342  return 0;
343  }
344  }
345  else
346  {
347  $this->error=$this->db->lasterror();
348  return -1;
349  }
350 
351  // To get back the global configuration unique to the user
352  if ($loadpersonalconf)
353  {
354  // Load user->conf for user
355  $sql = "SELECT param, value FROM ".MAIN_DB_PREFIX."user_param";
356  $sql.= " WHERE fk_user = ".$this->id;
357  $sql.= " AND entity = ".$conf->entity;
358  //dol_syslog(get_class($this).'::fetch load personalized conf', LOG_DEBUG);
359  $resql=$this->db->query($sql);
360  if ($resql)
361  {
362  $num = $this->db->num_rows($resql);
363  $i = 0;
364  while ($i < $num)
365  {
366  $obj = $this->db->fetch_object($resql);
367  $p=(! empty($obj->param)?$obj->param:'');
368  if (! empty($p)) $this->conf->$p = $obj->value;
369  $i++;
370  }
371  $this->db->free($resql);
372  }
373  else
374  {
375  $this->error=$this->db->lasterror();
376  return -2;
377  }
378 
379  // Load user->default_values for user. TODO Save this in memcached ?
380  $sql = "SELECT rowid, entity, type, page, param, value";
381  $sql.= " FROM ".MAIN_DB_PREFIX."default_values";
382  $sql.= " WHERE entity IN (".$this->entity.",".$conf->entity.")";
383  $sql.= " AND user_id IN (0, ".$this->id.")";
384  $resql = $this->db->query($sql);
385  if ($resql)
386  {
387  while ($obj = $this->db->fetch_object($resql))
388  {
389  if (! empty($obj->page) && ! empty($obj->type) && ! empty($obj->param))
390  {
391  // $obj->page is relative URL with or without params
392  // $obj->type can be 'filters', 'sortorder', 'createform', ...
393  // $obj->param is key or param
394  $pagewithoutquerystring=$obj->page;
395  $pagequeries='';
396  if (preg_match('/^([^\?]+)\?(.*)$/', $pagewithoutquerystring, $reg)) // There is query param
397  {
398  $pagewithoutquerystring=$reg[1];
399  $pagequeries=$reg[2];
400  }
401  $this->default_values[$pagewithoutquerystring][$obj->type][$pagequeries?$pagequeries:'_noquery_'][$obj->param]=$obj->value;
402  //if ($pagequeries) $this->default_values[$pagewithoutquerystring][$obj->type.'_queries']=$pagequeries;
403  }
404  }
405  // Sort by key, so _noquery_ is last
406  if(!empty($this->default_values)) {
407  foreach($this->default_values as $a => $b)
408  {
409  foreach($b as $c => $d)
410  {
411  krsort($this->default_values[$a][$c]);
412  }
413  }
414  }
415  $this->db->free($resql);
416  }
417  else
418  {
419  $this->error=$this->db->lasterror();
420  return -3;
421  }
422  }
423 
424  return 1;
425  }
426 
438  function addrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0)
439  {
440  global $conf, $user, $langs;
441 
442  $entity = (! empty($entity)?$entity:$conf->entity);
443 
444  dol_syslog(get_class($this)."::addrights $rid, $allmodule, $allperms, $entity");
445  $error=0;
446  $whereforadd='';
447 
448  $this->db->begin();
449 
450  if (! empty($rid))
451  {
452  // Si on a demande ajout d'un droit en particulier, on recupere
453  // les caracteristiques (module, perms et subperms) de ce droit.
454  $sql = "SELECT module, perms, subperms";
455  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
456  $sql.= " WHERE id = '".$this->db->escape($rid)."'";
457  $sql.= " AND entity = ".$entity;
458 
459  $result=$this->db->query($sql);
460  if ($result) {
461  $obj = $this->db->fetch_object($result);
462  $module=$obj->module;
463  $perms=$obj->perms;
464  $subperms=$obj->subperms;
465  }
466  else {
467  $error++;
468  dol_print_error($this->db);
469  }
470 
471  // Where pour la liste des droits a ajouter
472  $whereforadd="id=".$this->db->escape($rid);
473  // Ajout des droits induits
474  if (! empty($subperms)) $whereforadd.=" OR (module='$module' AND perms='$perms' AND (subperms='lire' OR subperms='read'))";
475  else if (! empty($perms)) $whereforadd.=" OR (module='$module' AND (perms='lire' OR perms='read') AND subperms IS NULL)";
476  }
477  else {
478  // On a pas demande un droit en particulier mais une liste de droits
479  // sur la base d'un nom de module de de perms
480  // Where pour la liste des droits a ajouter
481  if (! empty($allmodule))
482  {
483  $whereforadd="module='".$this->db->escape($allmodule)."'";
484  if (! empty($allperms)) $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
485  }
486  }
487 
488  // Ajout des droits trouves grace au critere whereforadd
489  if (! empty($whereforadd))
490  {
491  //print "$module-$perms-$subperms";
492  $sql = "SELECT id";
493  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
494  $sql.= " WHERE ".$whereforadd;
495  $sql.= " AND entity = ".$entity;
496 
497  $result=$this->db->query($sql);
498  if ($result)
499  {
500  $num = $this->db->num_rows($result);
501  $i = 0;
502  while ($i < $num)
503  {
504  $obj = $this->db->fetch_object($result);
505  $nid = $obj->id;
506 
507  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id." AND fk_id=".$nid." AND entity = ".$entity;
508  if (! $this->db->query($sql)) $error++;
509  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (entity, fk_user, fk_id) VALUES (".$entity.", ".$this->id.", ".$nid.")";
510  if (! $this->db->query($sql)) $error++;
511 
512  $i++;
513  }
514  }
515  else
516  {
517  $error++;
518  dol_print_error($this->db);
519  }
520  }
521 
522  if (! $error && ! $notrigger)
523  {
524  $langs->load("other");
525  $this->context = array('audit'=>$langs->trans("PermissionsAdd").($rid?' (id='.$rid.')':''));
526 
527  // Call trigger
528  $result=$this->call_trigger('USER_MODIFY',$user);
529  if ($result < 0) { $error++; }
530  // End call triggers
531  }
532 
533  if ($error) {
534  $this->db->rollback();
535  return -$error;
536  }
537  else {
538  $this->db->commit();
539  return 1;
540  }
541 
542  }
543 
544 
556  function delrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0)
557  {
558  global $conf, $user, $langs;
559 
560  $error=0;
561  $wherefordel='';
562  $entity = (! empty($entity)?$entity:$conf->entity);
563 
564  $this->db->begin();
565 
566  if (! empty($rid))
567  {
568  // Si on a demande supression d'un droit en particulier, on recupere
569  // les caracteristiques module, perms et subperms de ce droit.
570  $sql = "SELECT module, perms, subperms";
571  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
572  $sql.= " WHERE id = '".$this->db->escape($rid)."'";
573  $sql.= " AND entity = ".$entity;
574 
575  $result=$this->db->query($sql);
576  if ($result) {
577  $obj = $this->db->fetch_object($result);
578  $module=$obj->module;
579  $perms=$obj->perms;
580  $subperms=$obj->subperms;
581  }
582  else {
583  $error++;
584  dol_print_error($this->db);
585  }
586 
587  // Where pour la liste des droits a supprimer
588  $wherefordel="id=".$this->db->escape($rid);
589  // Suppression des droits induits
590  if ($subperms=='lire' || $subperms=='read') $wherefordel.=" OR (module='$module' AND perms='$perms' AND subperms IS NOT NULL)";
591  if ($perms=='lire' || $perms=='read') $wherefordel.=" OR (module='$module')";
592  }
593  else {
594  // On a demande suppression d'un droit sur la base d'un nom de module ou perms
595  // Where pour la liste des droits a supprimer
596  if (! empty($allmodule)) $wherefordel="module='".$this->db->escape($allmodule)."'";
597  if (! empty($allperms)) $wherefordel=" AND perms='".$this->db->escape($allperms)."'";
598  }
599 
600  // Suppression des droits selon critere defini dans wherefordel
601  if (! empty($wherefordel))
602  {
603  //print "$module-$perms-$subperms";
604  $sql = "SELECT id";
605  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
606  $sql.= " WHERE $wherefordel";
607  $sql.= " AND entity = ".$entity;
608 
609  $result=$this->db->query($sql);
610  if ($result)
611  {
612  $num = $this->db->num_rows($result);
613  $i = 0;
614  while ($i < $num)
615  {
616  $obj = $this->db->fetch_object($result);
617  $nid = $obj->id;
618 
619  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights";
620  $sql.= " WHERE fk_user = ".$this->id." AND fk_id=".$nid;
621  $sql.= " AND entity = ".$entity;
622  if (! $this->db->query($sql)) $error++;
623 
624  $i++;
625  }
626  }
627  else
628  {
629  $error++;
630  dol_print_error($this->db);
631  }
632  }
633 
634  if (! $error && ! $notrigger)
635  {
636  $langs->load("other");
637  $this->context = array('audit'=>$langs->trans("PermissionsDelete").($rid?' (id='.$rid.')':''));
638 
639  // Call trigger
640  $result=$this->call_trigger('USER_MODIFY',$user);
641  if ($result < 0) { $error++; }
642  // End call triggers
643  }
644 
645  if ($error) {
646  $this->db->rollback();
647  return -$error;
648  }
649  else {
650  $this->db->commit();
651  return 1;
652  }
653 
654  }
655 
656 
663  function clearrights()
664  {
665  dol_syslog(get_class($this)."::clearrights reset user->rights");
666  $this->rights='';
667  $this->all_permissions_are_loaded=false;
668  $this->_tab_loaded=array();
669  }
670 
671 
679  function getrights($moduletag='')
680  {
681  global $conf;
682 
683  if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag])
684  {
685  // Le fichier de ce module est deja charge
686  return;
687  }
688 
689  if ($this->all_permissions_are_loaded)
690  {
691  // Si les permissions ont deja ete charge pour ce user, on quitte
692  return;
693  }
694 
695  // Recuperation des droits utilisateurs + recuperation des droits groupes
696 
697  // D'abord les droits utilisateurs
698  $sql = "SELECT r.module, r.perms, r.subperms";
699  $sql.= " FROM ".MAIN_DB_PREFIX."user_rights as ur";
700  $sql.= ", ".MAIN_DB_PREFIX."rights_def as r";
701  $sql.= " WHERE r.id = ur.fk_id";
702  if (! empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY))
703  {
704  $sql.= " AND r.entity IN (0,".(! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)?"1,":"").$conf->entity.")";
705  }
706  else
707  {
708  $sql.= " AND ur.entity = ".$conf->entity;
709  }
710  $sql.= " AND ur.fk_user= ".$this->id;
711  $sql.= " AND r.perms IS NOT NULL";
712  if ($moduletag) $sql.= " AND r.module = '".$this->db->escape($moduletag)."'";
713 
714  $resql = $this->db->query($sql);
715  if ($resql)
716  {
717  $num = $this->db->num_rows($resql);
718  $i = 0;
719  while ($i < $num)
720  {
721  $obj = $this->db->fetch_object($resql);
722 
723  $module=$obj->module;
724  $perms=$obj->perms;
725  $subperms=$obj->subperms;
726 
727  if ($perms)
728  {
729  if (! isset($this->rights) || ! is_object($this->rights)) $this->rights = new stdClass(); // For avoid error
730  if ($module)
731  {
732  if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
733  if ($subperms)
734  {
735  if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
736  if(empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++;
737  $this->rights->$module->$perms->$subperms = 1;
738  }
739  else
740  {
741  if(empty($this->rights->$module->$perms)) $this->nb_rights++;
742  $this->rights->$module->$perms = 1;
743  }
744  }
745  }
746  $i++;
747  }
748  $this->db->free($resql);
749  }
750 
751  // Maintenant les droits groupes
752  $sql = "SELECT r.module, r.perms, r.subperms";
753  $sql.= " FROM ".MAIN_DB_PREFIX."usergroup_rights as gr,";
754  $sql.= " ".MAIN_DB_PREFIX."usergroup_user as gu,";
755  $sql.= " ".MAIN_DB_PREFIX."rights_def as r";
756  $sql.= " WHERE r.id = gr.fk_id";
757  if (! empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY))
758  {
759  if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
760  $sql.= " AND gu.entity IN (0,".$conf->entity.")";
761  } else {
762  $sql.= " AND r.entity = ".$conf->entity;
763  }
764  }
765  else
766  {
767  $sql.= " AND gr.entity = ".$conf->entity;
768  $sql.= " AND r.entity = ".$conf->entity;
769  }
770  $sql.= " AND gr.fk_usergroup = gu.fk_usergroup";
771  $sql.= " AND gu.fk_user = ".$this->id;
772  $sql.= " AND r.perms IS NOT NULL";
773  if ($moduletag) $sql.= " AND r.module = '".$this->db->escape($moduletag)."'";
774 
775  $resql = $this->db->query($sql);
776  if ($resql)
777  {
778  $num = $this->db->num_rows($resql);
779  $i = 0;
780  while ($i < $num)
781  {
782  $obj = $this->db->fetch_object($resql);
783 
784  $module=$obj->module;
785  $perms=$obj->perms;
786  $subperms=$obj->subperms;
787 
788  if ($perms)
789  {
790  if (! isset($this->rights) || ! is_object($this->rights)) $this->rights = new stdClass(); // For avoid error
791  if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
792  if ($subperms)
793  {
794  if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
795  if(empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++;
796  $this->rights->$module->$perms->$subperms = 1;
797  }
798  else
799  {
800  if(empty($this->rights->$module->$perms)) $this->nb_rights++;
801  $this->rights->$module->$perms = 1;
802  }
803 
804  }
805  $i++;
806  }
807  $this->db->free($resql);
808  }
809 
810  // For backward compatibility
811  if (isset($this->rights->propale) && ! isset($this->rights->propal)) $this->rights->propal = $this->rights->propale;
812  if (isset($this->rights->propal) && ! isset($this->rights->propale)) $this->rights->propale = $this->rights->propal;
813 
814  if (! $moduletag)
815  {
816  // Si module etait non defini, alors on a tout charge, on peut donc considerer
817  // que les droits sont en cache (car tous charges) pour cet instance de user
818  $this->all_permissions_are_loaded=1;
819  }
820  else
821  {
822  // Si module defini, on le marque comme charge en cache
823  $this->_tab_loaded[$moduletag]=1;
824  }
825  }
826 
833  function setstatus($statut)
834  {
835  global $conf,$langs,$user;
836 
837  $error=0;
838 
839  // Check parameters
840  if ($this->statut == $statut) return 0;
841  else $this->statut = $statut;
842 
843  $this->db->begin();
844 
845  // Deactivate user
846  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
847  $sql.= " SET statut = ".$this->statut;
848  $sql.= " WHERE rowid = ".$this->id;
849  $result = $this->db->query($sql);
850 
851  dol_syslog(get_class($this)."::setstatus", LOG_DEBUG);
852  if ($result)
853  {
854  // Call trigger
855  $result=$this->call_trigger('USER_ENABLEDISABLE',$user);
856  if ($result < 0) { $error++; }
857  // End call triggers
858  }
859 
860  if ($error)
861  {
862  $this->db->rollback();
863  return -$error;
864  }
865  else
866  {
867  $this->db->commit();
868  return 1;
869  }
870  }
871 
881  public function setCategories($categories)
882  {
883  // Handle single category
884  if (!is_array($categories)) {
885  $categories = array($categories);
886  }
887 
888  // Get current categories
889  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
890  $c = new Categorie($this->db);
891  $existing = $c->containing($this->id, Categorie::TYPE_USER, 'id');
892 
893  // Diff
894  if (is_array($existing)) {
895  $to_del = array_diff($existing, $categories);
896  $to_add = array_diff($categories, $existing);
897  } else {
898  $to_del = array(); // Nothing to delete
899  $to_add = $categories;
900  }
901 
902  // Process
903  foreach ($to_del as $del) {
904  if ($c->fetch($del) > 0) {
905  $c->del_type($this, 'user');
906  }
907  }
908  foreach ($to_add as $add) {
909  if ($c->fetch($add) > 0) {
910  $c->add_type($this, 'user');
911  }
912  }
913 
914  return;
915  }
916 
922  function delete()
923  {
924  global $user,$conf,$langs;
925 
926  $error=0;
927 
928  $this->db->begin();
929 
930  $this->fetch($this->id);
931 
932  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
933 
934  // Remove rights
935  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id;
936 
937  if (! $error && ! $this->db->query($sql))
938  {
939  $error++;
940  $this->error = $this->db->lasterror();
941  }
942 
943  // Remove group
944  $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user WHERE fk_user = ".$this->id;
945  if (! $error && ! $this->db->query($sql))
946  {
947  $error++;
948  $this->error = $this->db->lasterror();
949  }
950 
951  // If contact, remove link
952  if ($this->contact_id)
953  {
954  $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET fk_user_creat = null WHERE rowid = ".$this->contact_id;
955  if (! $error && ! $this->db->query($sql))
956  {
957  $error++;
958  $this->error = $this->db->lasterror();
959  }
960  }
961 
962  // Remove extrafields
963  if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
964  {
965  $result=$this->deleteExtraFields();
966  if ($result < 0)
967  {
968  $error++;
969  dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
970  }
971  }
972 
973  // Remove user
974  if (! $error)
975  {
976  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->id;
977  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
978  if (! $this->db->query($sql))
979  {
980  $error++;
981  $this->error = $this->db->lasterror();
982  }
983  }
984 
985  if (! $error)
986  {
987  // Call trigger
988  $result=$this->call_trigger('USER_DELETE',$user);
989  if ($result < 0)
990  {
991  $error++;
992  $this->db->rollback();
993  return -1;
994  }
995  // End call triggers
996 
997  $this->db->commit();
998  return 1;
999  }
1000  else
1001  {
1002  $this->db->rollback();
1003  return -1;
1004  }
1005  }
1006 
1014  function create($user, $notrigger=0)
1015  {
1016  global $conf,$langs;
1017  global $mysoc;
1018 
1019  // Clean parameters
1020  $this->login = trim($this->login);
1021  if (! isset($this->entity)) $this->entity=$conf->entity; // If not defined, we use default value
1022 
1023  dol_syslog(get_class($this)."::create login=".$this->login.", user=".(is_object($user)?$user->id:''), LOG_DEBUG);
1024 
1025  // Check parameters
1026  if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
1027  {
1028  $langs->load("errors");
1029  $this->error = $langs->trans("ErrorBadEMail",$this->email);
1030  return -1;
1031  }
1032  if (empty($this->login))
1033  {
1034  $langs->load("errors");
1035  $this->error = $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Login"));
1036  return -1;
1037  }
1038 
1039  $this->datec = dol_now();
1040 
1041  $error=0;
1042  $this->db->begin();
1043 
1044  $sql = "SELECT login FROM ".MAIN_DB_PREFIX."user";
1045  $sql.= " WHERE login ='".$this->db->escape($this->login)."'";
1046  $sql.= " AND entity IN (0,".$this->db->escape($conf->entity).")";
1047 
1048  dol_syslog(get_class($this)."::create", LOG_DEBUG);
1049  $resql=$this->db->query($sql);
1050  if ($resql)
1051  {
1052  $num = $this->db->num_rows($resql);
1053  $this->db->free($resql);
1054 
1055  if ($num)
1056  {
1057  $this->error = 'ErrorLoginAlreadyExists';
1058  dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
1059  $this->db->rollback();
1060  return -6;
1061  }
1062  else
1063  {
1064  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user (datec,login,ldap_sid,entity)";
1065  $sql.= " VALUES('".$this->db->idate($this->datec)."','".$this->db->escape($this->login)."','".$this->db->escape($this->ldap_sid)."',".$this->db->escape($this->entity).")";
1066  $result=$this->db->query($sql);
1067 
1068  dol_syslog(get_class($this)."::create", LOG_DEBUG);
1069  if ($result)
1070  {
1071  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."user");
1072 
1073  // Set default rights
1074  if ($this->set_default_rights() < 0)
1075  {
1076  $this->error='ErrorFailedToSetDefaultRightOfUser';
1077  $this->db->rollback();
1078  return -5;
1079  }
1080 
1081  // Update minor fields
1082  $result = $this->update($user,1,1);
1083  if ($result < 0)
1084  {
1085  $this->db->rollback();
1086  return -4;
1087  }
1088 
1089  if (! empty($conf->global->STOCK_USERSTOCK_AUTOCREATE))
1090  {
1091  require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1092  $langs->load("stocks");
1093  $entrepot = new Entrepot($this->db);
1094  $entrepot->libelle = $langs->trans("PersonalStock",$this->getFullName($langs));
1095  $entrepot->description = $langs->trans("ThisWarehouseIsPersonalStock",$this->getFullName($langs));
1096  $entrepot->statut = 1;
1097  $entrepot->country_id = $mysoc->country_id;
1098  $entrepot->create($user);
1099  }
1100 
1101  if (! $notrigger)
1102  {
1103  // Call trigger
1104  $result=$this->call_trigger('USER_CREATE',$user);
1105  if ($result < 0) { $error++; }
1106  // End call triggers
1107  }
1108 
1109  if (! $error)
1110  {
1111  $this->db->commit();
1112  return $this->id;
1113  }
1114  else
1115  {
1116  //$this->error=$interface->error;
1117  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
1118  $this->db->rollback();
1119  return -3;
1120  }
1121  }
1122  else
1123  {
1124  $this->error=$this->db->lasterror();
1125  $this->db->rollback();
1126  return -2;
1127  }
1128  }
1129  }
1130  else
1131  {
1132  $this->error=$this->db->lasterror();
1133  $this->db->rollback();
1134  return -1;
1135  }
1136  }
1137 
1138 
1147  function create_from_contact($contact,$login='',$password='')
1148  {
1149  global $conf,$user,$langs;
1150 
1151  $error=0;
1152 
1153  // Define parameters
1154  $this->admin = 0;
1155  $this->lastname = $contact->lastname;
1156  $this->firstname = $contact->firstname;
1157  $this->gender = $contact->gender;
1158  $this->email = $contact->email;
1159  $this->skype = $contact->skype;
1160  $this->office_phone = $contact->phone_pro;
1161  $this->office_fax = $contact->fax;
1162  $this->user_mobile = $contact->phone_mobile;
1163  $this->address = $contact->address;
1164  $this->zip = $contact->zip;
1165  $this->town = $contact->town;
1166  $this->state_id = $contact->state_id;
1167  $this->country_id = $contact->country_id;
1168  $this->employee = 0;
1169 
1170  if (empty($login)) $login=strtolower(substr($contact->firstname, 0, 4)) . strtolower(substr($contact->lastname, 0, 4));
1171  $this->login = $login;
1172 
1173  $this->db->begin();
1174 
1175  // Cree et positionne $this->id
1176  $result=$this->create($user);
1177  if ($result > 0)
1178  {
1179  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1180  $sql.= " SET fk_socpeople=".$contact->id;
1181  if ($contact->socid) $sql.=", fk_soc=".$contact->socid;
1182  $sql.= " WHERE rowid=".$this->id;
1183  $resql=$this->db->query($sql);
1184 
1185  dol_syslog(get_class($this)."::create_from_contact", LOG_DEBUG);
1186  if ($resql)
1187  {
1188  $this->context['createfromcontact']='createfromcontact';
1189 
1190  // Call trigger
1191  $result=$this->call_trigger('USER_CREATE',$user);
1192  if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1193  // End call triggers
1194 
1195  $this->db->commit();
1196  return $this->id;
1197  }
1198  else
1199  {
1200  $this->error=$this->db->error();
1201 
1202  $this->db->rollback();
1203  return -1;
1204  }
1205  }
1206  else
1207  {
1208  // $this->error deja positionne
1209  dol_syslog(get_class($this)."::create_from_contact - 0");
1210 
1211  $this->db->rollback();
1212  return $result;
1213  }
1214 
1215  }
1216 
1224  function create_from_member($member,$login='')
1225  {
1226  global $conf,$user,$langs;
1227 
1228  // Positionne parametres
1229  $this->admin = 0;
1230  $this->lastname = $member->lastname;
1231  $this->firstname = $member->firstname;
1232  $this->gender = $member->gender;
1233  $this->email = $member->email;
1234  $this->fk_member = $member->id;
1235  $this->pass = $member->pass;
1236  $this->address = $member->address;
1237  $this->zip = $member->zip;
1238  $this->town = $member->town;
1239  $this->state_id = $member->state_id;
1240  $this->country_id = $member->country_id;
1241 
1242  if (empty($login)) $login=strtolower(substr($member->firstname, 0, 4)) . strtolower(substr($member->lastname, 0, 4));
1243  $this->login = $login;
1244 
1245  $this->db->begin();
1246 
1247  // Create and set $this->id
1248  $result=$this->create($user);
1249  if ($result > 0)
1250  {
1251  $newpass=$this->setPassword($user,$this->pass);
1252  if (is_numeric($newpass) && $newpass < 0) $result=-2;
1253 
1254  if ($result > 0 && $member->fk_soc) // If member is linked to a thirdparty
1255  {
1256  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1257  $sql.= " SET fk_soc=".$member->fk_soc;
1258  $sql.= " WHERE rowid=".$this->id;
1259 
1260  dol_syslog(get_class($this)."::create_from_member", LOG_DEBUG);
1261  $resql=$this->db->query($sql);
1262  if ($resql)
1263  {
1264  $this->db->commit();
1265  return $this->id;
1266  }
1267  else
1268  {
1269  $this->error=$this->db->lasterror();
1270 
1271  $this->db->rollback();
1272  return -1;
1273  }
1274  }
1275  }
1276 
1277  if ($result > 0)
1278  {
1279  $this->db->commit();
1280  return $this->id;
1281  }
1282  else
1283  {
1284  // $this->error deja positionne
1285  $this->db->rollback();
1286  return -2;
1287  }
1288  }
1289 
1296  {
1297  global $conf;
1298 
1299  $sql = "SELECT id FROM ".MAIN_DB_PREFIX."rights_def";
1300  $sql.= " WHERE bydefault = 1";
1301  $sql.= " AND entity = ".$conf->entity;
1302 
1303  $resql=$this->db->query($sql);
1304  if ($resql)
1305  {
1306  $num = $this->db->num_rows($resql);
1307  $i = 0;
1308  $rd = array();
1309  while ($i < $num)
1310  {
1311  $row = $this->db->fetch_row($resql);
1312  $rd[$i] = $row[0];
1313  $i++;
1314  }
1315  $this->db->free($resql);
1316  }
1317  $i = 0;
1318  while ($i < $num)
1319  {
1320 
1321  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = $this->id AND fk_id=$rd[$i]";
1322  $result=$this->db->query($sql);
1323 
1324  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (fk_user, fk_id) VALUES ($this->id, $rd[$i])";
1325  $result=$this->db->query($sql);
1326  if (! $result) return -1;
1327  $i++;
1328  }
1329 
1330  return $i;
1331  }
1332 
1343  function update($user, $notrigger=0, $nosyncmember=0, $nosyncmemberpass=0, $nosynccontact=0)
1344  {
1345  global $conf, $langs;
1346 
1347  $nbrowsaffected=0;
1348  $error=0;
1349 
1350  dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncmember=".$nosyncmember.", nosyncmemberpass=".$nosyncmemberpass);
1351 
1352  // Clean parameters
1353  $this->lastname = trim($this->lastname);
1354  $this->firstname = trim($this->firstname);
1355  $this->employee = $this->employee?$this->employee:0;
1356  $this->login = trim($this->login);
1357  $this->gender = trim($this->gender);
1358  $this->birth = trim($this->birth);
1359  $this->pass = trim($this->pass);
1360  $this->api_key = trim($this->api_key);
1361  $this->address = $this->address?trim($this->address):trim($this->address);
1362  $this->zip = $this->zip?trim($this->zip):trim($this->zip);
1363  $this->town = $this->town?trim($this->town):trim($this->town);
1364  $this->state_id = trim($this->state_id);
1365  $this->country_id = ($this->country_id > 0)?$this->country_id:0;
1366  $this->office_phone = trim($this->office_phone);
1367  $this->office_fax = trim($this->office_fax);
1368  $this->user_mobile = trim($this->user_mobile);
1369  $this->email = trim($this->email);
1370  $this->skype = trim($this->skype);
1371  $this->job = trim($this->job);
1372  $this->signature = trim($this->signature);
1373  $this->note = trim($this->note);
1374  $this->openid = trim(empty($this->openid)?'':$this->openid); // Avoid warning
1375  $this->admin = $this->admin?$this->admin:0;
1376  $this->address = empty($this->address)?'':$this->address;
1377  $this->zip = empty($this->zip)?'':$this->zip;
1378  $this->town = empty($this->town)?'':$this->town;
1379  $this->accountancy_code = trim($this->accountancy_code);
1380  $this->color = empty($this->color)?'':$this->color;
1381  $this->dateemployment = empty($this->dateemployment)?'':$this->dateemployment;
1382 
1383  // Check parameters
1384  if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
1385  {
1386  $langs->load("errors");
1387  $this->error = $langs->trans("ErrorBadEMail",$this->email);
1388  return -1;
1389  }
1390  if (empty($this->login))
1391  {
1392  $langs->load("errors");
1393  $this->error = $langs->trans("ErrorFieldRequired",$this->login);
1394  return -1;
1395  }
1396 
1397  $this->db->begin();
1398 
1399  // Update datas
1400  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
1401  $sql.= " lastname = '".$this->db->escape($this->lastname)."'";
1402  $sql.= ", firstname = '".$this->db->escape($this->firstname)."'";
1403  $sql.= ", employee = ".$this->employee;
1404  $sql.= ", login = '".$this->db->escape($this->login)."'";
1405  $sql.= ", api_key = ".($this->api_key ? "'".$this->db->escape($this->api_key)."'" : "null");
1406  $sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
1407  $sql.= ", birth=".(strval($this->birth)!='' ? "'".$this->db->idate($this->birth)."'" : 'null');
1408  if (! empty($user->admin)) $sql.= ", admin = ".$this->admin; // admin flag can be set/unset only by an admin user
1409  $sql.= ", address = '".$this->db->escape($this->address)."'";
1410  $sql.= ", zip = '".$this->db->escape($this->zip)."'";
1411  $sql.= ", town = '".$this->db->escape($this->town)."'";
1412  $sql.= ", fk_state = ".((! empty($this->state_id) && $this->state_id > 0)?"'".$this->db->escape($this->state_id)."'":"null");
1413  $sql.= ", fk_country = ".((! empty($this->country_id) && $this->country_id > 0)?"'".$this->db->escape($this->country_id)."'":"null");
1414  $sql.= ", office_phone = '".$this->db->escape($this->office_phone)."'";
1415  $sql.= ", office_fax = '".$this->db->escape($this->office_fax)."'";
1416  $sql.= ", user_mobile = '".$this->db->escape($this->user_mobile)."'";
1417  $sql.= ", email = '".$this->db->escape($this->email)."'";
1418  $sql.= ", skype = '".$this->db->escape($this->skype)."'";
1419  $sql.= ", job = '".$this->db->escape($this->job)."'";
1420  $sql.= ", signature = '".$this->db->escape($this->signature)."'";
1421  $sql.= ", accountancy_code = '".$this->db->escape($this->accountancy_code)."'";
1422  $sql.= ", color = '".$this->db->escape($this->color)."'";
1423  $sql.= ", dateemployment=".(strval($this->dateemployment)!='' ? "'".$this->db->idate($this->dateemployment)."'" : 'null');
1424  $sql.= ", note = '".$this->db->escape($this->note)."'";
1425  $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null");
1426  $sql.= ", openid = ".($this->openid?"'".$this->db->escape($this->openid)."'":"null");
1427  $sql.= ", fk_user = ".($this->fk_user > 0?"'".$this->db->escape($this->fk_user)."'":"null");
1428  if (isset($this->thm) || $this->thm != '') $sql.= ", thm= ".($this->thm != ''?"'".$this->db->escape($this->thm)."'":"null");
1429  if (isset($this->tjm) || $this->tjm != '') $sql.= ", tjm= ".($this->tjm != ''?"'".$this->db->escape($this->tjm)."'":"null");
1430  if (isset($this->salary) || $this->salary != '') $sql.= ", salary= ".($this->salary != ''?"'".$this->db->escape($this->salary)."'":"null");
1431  if (isset($this->salaryextra) || $this->salaryextra != '') $sql.= ", salaryextra= ".($this->salaryextra != ''?"'".$this->db->escape($this->salaryextra)."'":"null");
1432  $sql.= ", weeklyhours= ".($this->weeklyhours != ''?"'".$this->db->escape($this->weeklyhours)."'":"null");
1433  $sql.= ", entity = '".$this->db->escape($this->entity)."'";
1434  $sql.= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null');
1435  $sql.= ", default_c_exp_tax_cat = ".($this->default_c_exp_tax_cat > 0 ? $this->default_c_exp_tax_cat : 'null');
1436 
1437  $sql.= " WHERE rowid = ".$this->id;
1438 
1439  dol_syslog(get_class($this)."::update", LOG_DEBUG);
1440  $resql = $this->db->query($sql);
1441  if ($resql)
1442  {
1443  $nbrowsaffected+=$this->db->affected_rows($resql);
1444 
1445  // Update password
1446  if (!empty($this->pass))
1447  {
1448  if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted)
1449  {
1450  // Si mot de passe saisi et different de celui en base
1451  $result=$this->setPassword($user,$this->pass,0,$notrigger,$nosyncmemberpass);
1452  if (! $nbrowsaffected) $nbrowsaffected++;
1453  }
1454  }
1455 
1456  // If user is linked to a member, remove old link to this member
1457  if ($this->fk_member > 0)
1458  {
1459  dol_syslog(get_class($this)."::update remove link with member. We will recreate it later", LOG_DEBUG);
1460  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member;
1461  $resql = $this->db->query($sql);
1462  if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
1463  }
1464  // Set link to user
1465  dol_syslog(get_class($this)."::update set link with member", LOG_DEBUG);
1466  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member =".($this->fk_member>0?$this->fk_member:'null')." where rowid = ".$this->id;
1467  $resql = $this->db->query($sql);
1468  if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
1469 
1470  if ($nbrowsaffected) // If something has changed in data
1471  {
1472  if ($this->fk_member > 0 && ! $nosyncmember)
1473  {
1474  dol_syslog(get_class($this)."::update user is linked with a member. We try to update member too.", LOG_DEBUG);
1475 
1476  require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1477 
1478  // This user is linked with a member, so we also update member information
1479  // if this is an update.
1480  $adh=new Adherent($this->db);
1481  $result=$adh->fetch($this->fk_member);
1482 
1483  if ($result >= 0)
1484  {
1485  $adh->firstname=$this->firstname;
1486  $adh->lastname=$this->lastname;
1487  $adh->login=$this->login;
1488  $adh->gender=$this->gender;
1489  $adh->birth=$this->birth;
1490 
1491  $adh->pass=$this->pass;
1492 
1493  $adh->societe=(empty($adh->societe) && $this->societe_id ? $this->societe_id : $adh->societe);
1494 
1495  $adh->email=$this->email;
1496  $adh->skype=$this->skype;
1497  $adh->phone=$this->office_phone;
1498  $adh->phone_mobile=$this->user_mobile;
1499 
1500  $adh->user_id=$this->id;
1501  $adh->user_login=$this->login;
1502 
1503  $result=$adh->update($user,0,1,0);
1504  if ($result < 0)
1505  {
1506  $this->error=$adh->error;
1507  $this->errors=$adh->errors;
1508  dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR);
1509  $error++;
1510  }
1511  }
1512  else
1513  {
1514  $this->error=$adh->error;
1515  $this->errors=$adh->errors;
1516  $error++;
1517  }
1518  }
1519 
1520  if ($this->contact_id > 0 && ! $nosynccontact)
1521  {
1522  dol_syslog(get_class($this)."::update user is linked with a contact. We try to update contact too.", LOG_DEBUG);
1523 
1524  require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
1525 
1526  // This user is linked with a contact, so we also update contact information
1527  // if this is an update.
1528  $tmpobj=new Contact($this->db);
1529  $result=$tmpobj->fetch($this->contact_id);
1530 
1531  if ($result >= 0)
1532  {
1533  $tmpobj->firstname=$this->firstname;
1534  $tmpobj->lastname=$this->lastname;
1535  $tmpobj->login=$this->login;
1536  $tmpobj->gender=$this->gender;
1537  $tmpobj->birth=$this->birth;
1538 
1539  //$tmpobj->pass=$this->pass;
1540 
1541  //$tmpobj->societe=(empty($tmpobj->societe) && $this->societe_id ? $this->societe_id : $tmpobj->societe);
1542 
1543  $tmpobj->email=$this->email;
1544  $tmpobj->skype=$this->skype;
1545  $tmpobj->phone_pro=$this->office_phone;
1546  $tmpobj->phone_mobile=$this->user_mobile;
1547  $tmpobj->fax=$this->office_fax;
1548 
1549  $tmpobj->address=$this->address;
1550  $tmpobj->town=$this->town;
1551  $tmpobj->zip=$this->zip;
1552  $tmpobj->state_id=$this->state_id;
1553  $tmpobj->country_id=$this->country_id;
1554 
1555  $tmpobj->user_id=$this->id;
1556  $tmpobj->user_login=$this->login;
1557 
1558  $result=$tmpobj->update($tmpobj->id, $user, 0, 'update', 1);
1559  if ($result < 0)
1560  {
1561  $this->error=$tmpobj->error;
1562  $this->errors=$tmpobj->errors;
1563  dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR);
1564  $error++;
1565  }
1566  }
1567  else
1568  {
1569  $this->error=$tmpobj->error;
1570  $this->errors=$tmpobj->errors;
1571  $error++;
1572  }
1573  }
1574  }
1575 
1576  $action='update';
1577 
1578  // Actions on extra fields (by external module or standard code)
1579  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
1580  {
1581  $result=$this->insertExtraFields();
1582  if ($result < 0)
1583  {
1584  $error++;
1585  }
1586  }
1587 
1588  if (! $error && ! $notrigger)
1589  {
1590  // Call trigger
1591  $result=$this->call_trigger('USER_MODIFY',$user);
1592  if ($result < 0) { $error++; }
1593  // End call triggers
1594  }
1595 
1596  if (! $error)
1597  {
1598  $this->db->commit();
1599  return $nbrowsaffected;
1600  }
1601  else
1602  {
1603  dol_syslog(get_class($this)."::update error=".$this->error,LOG_ERR);
1604  $this->db->rollback();
1605  return -1;
1606  }
1607  }
1608  else
1609  {
1610  $this->error=$this->db->lasterror();
1611  $this->db->rollback();
1612  return -2;
1613  }
1614 
1615  }
1616 
1624  {
1625  $now=dol_now();
1626 
1627  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
1628  $sql.= " datepreviouslogin = datelastlogin,";
1629  $sql.= " datelastlogin = '".$this->db->idate($now)."',";
1630  $sql.= " tms = tms"; // La date de derniere modif doit changer sauf pour la mise a jour de date de derniere connexion
1631  $sql.= " WHERE rowid = ".$this->id;
1632 
1633  dol_syslog(get_class($this)."::update_last_login_date user->id=".$this->id." ".$sql, LOG_DEBUG);
1634  $resql = $this->db->query($sql);
1635  if ($resql)
1636  {
1637  $this->datepreviouslogin=$this->datelastlogin;
1638  $this->datelastlogin=$now;
1639  return 1;
1640  }
1641  else
1642  {
1643  $this->error=$this->db->lasterror().' sql='.$sql;
1644  return -1;
1645  }
1646  }
1647 
1648 
1659  function setPassword($user, $password='', $changelater=0, $notrigger=0, $nosyncmember=0)
1660  {
1661  global $conf, $langs;
1662  require_once DOL_DOCUMENT_ROOT .'/core/lib/security2.lib.php';
1663 
1664  $error=0;
1665 
1666  dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." changelater=".$changelater." notrigger=".$notrigger." nosyncmember=".$nosyncmember, LOG_DEBUG);
1667 
1668  // If new password not provided, we generate one
1669  if (! $password)
1670  {
1671  $password=getRandomPassword(false);
1672  }
1673 
1674  // Crypt password
1675  $password_crypted = dol_hash($password);
1676 
1677  // Mise a jour
1678  if (! $changelater)
1679  {
1680  if (! is_object($this->oldcopy)) $this->oldcopy = clone $this;
1681 
1682  $this->db->begin();
1683 
1684  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1685  $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."',";
1686  $sql.= " pass_temp = null";
1687  if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
1688  {
1689  $sql.= ", pass = null";
1690  }
1691  else
1692  {
1693  $sql.= ", pass = '".$this->db->escape($password)."'";
1694  }
1695  $sql.= " WHERE rowid = ".$this->id;
1696 
1697  dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1698  $result = $this->db->query($sql);
1699  if ($result)
1700  {
1701  if ($this->db->affected_rows($result))
1702  {
1703  $this->pass=$password;
1704  $this->pass_indatabase=$password;
1705  $this->pass_indatabase_crypted=$password_crypted;
1706 
1707  if ($this->fk_member && ! $nosyncmember)
1708  {
1709  require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1710 
1711  // This user is linked with a member, so we also update members informations
1712  // if this is an update.
1713  $adh=new Adherent($this->db);
1714  $result=$adh->fetch($this->fk_member);
1715 
1716  if ($result >= 0)
1717  {
1718  $result=$adh->setPassword($user,$this->pass,(empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1),1); // Cryptage non gere dans module adherent
1719  if ($result < 0)
1720  {
1721  $this->error=$adh->error;
1722  dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR);
1723  $error++;
1724  }
1725  }
1726  else
1727  {
1728  $this->error=$adh->error;
1729  $error++;
1730  }
1731  }
1732 
1733  dol_syslog(get_class($this)."::setPassword notrigger=".$notrigger." error=".$error,LOG_DEBUG);
1734 
1735  if (! $error && ! $notrigger)
1736  {
1737  // Call trigger
1738  $result=$this->call_trigger('USER_NEW_PASSWORD',$user);
1739  if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1740  // End call triggers
1741  }
1742 
1743  $this->db->commit();
1744  return $this->pass;
1745  }
1746  else
1747  {
1748  $this->db->rollback();
1749  return 0;
1750  }
1751  }
1752  else
1753  {
1754  $this->db->rollback();
1755  dol_print_error($this->db);
1756  return -1;
1757  }
1758  }
1759  else
1760  {
1761  // We store clear password in password temporary field.
1762  // After receiving confirmation link, we will crypt it and store it in pass_crypted
1763  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1764  $sql.= " SET pass_temp = '".$this->db->escape($password)."'";
1765  $sql.= " WHERE rowid = ".$this->id;
1766 
1767  dol_syslog(get_class($this)."::setPassword", LOG_DEBUG); // No log
1768  $result = $this->db->query($sql);
1769  if ($result)
1770  {
1771  return $password;
1772  }
1773  else
1774  {
1775  dol_print_error($this->db);
1776  return -3;
1777  }
1778  }
1779  }
1780 
1781 
1790  function send_password($user, $password='', $changelater=0)
1791  {
1792  global $conf,$langs;
1793  global $dolibarr_main_url_root;
1794 
1795  require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
1796 
1797  $msgishtml=0;
1798 
1799  // Define $msg
1800  $mesg = '';
1801 
1802  $outputlangs=new Translate("",$conf);
1803  if (isset($this->conf->MAIN_LANG_DEFAULT)
1804  && $this->conf->MAIN_LANG_DEFAULT != 'auto')
1805  { // If user has defined its own language (rare because in most cases, auto is used)
1806  $outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT);
1807  }
1808  else
1809  { // If user has not defined its own language, we used current language
1810  $outputlangs=$langs;
1811  }
1812 
1813  $outputlangs->load("main");
1814  $outputlangs->load("errors");
1815  $outputlangs->load("users");
1816  $outputlangs->load("other");
1817 
1818  $appli=constant('DOL_APPLICATION_TITLE');
1819  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
1820 
1821  $subject = $outputlangs->transnoentitiesnoconv("SubjectNewPassword", $appli);
1822 
1823  // Define $urlwithroot
1824  $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
1825  $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
1826 
1827  if (! $changelater)
1828  {
1829  $url = $urlwithroot.'/';
1830 
1831  $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived").".\n";
1832  $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyIs")." :\n\n";
1833  $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n";
1834  $mesg.= $outputlangs->transnoentitiesnoconv("Password")." = ".$password."\n\n";
1835  $mesg.= "\n";
1836 
1837  $mesg.= $outputlangs->transnoentitiesnoconv("ClickHereToGoTo", $appli).': '.$url."\n\n";
1838  $mesg.= "--\n";
1839  $mesg.= $user->getFullName($outputlangs); // Username that make then sending
1840 
1841  dol_syslog(get_class($this)."::send_password changelater is off, url=".$url);
1842  }
1843  else
1844  {
1845  $url = $urlwithroot.'/user/passwordforgotten.php?action=validatenewpassword&username='.$this->login."&passwordhash=".dol_hash($password);
1846 
1847  $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived")."\n";
1848  $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyWillBe")." :\n\n";
1849  $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n";
1850  $mesg.= $outputlangs->transnoentitiesnoconv("Password")." = ".$password."\n\n";
1851  $mesg.= "\n";
1852  $mesg.= $outputlangs->transnoentitiesnoconv("YouMustClickToChange")." :\n";
1853  $mesg.= $url."\n\n";
1854  $mesg.= $outputlangs->transnoentitiesnoconv("ForgetIfNothing")."\n\n";
1855 
1856  dol_syslog(get_class($this)."::send_password changelater is on, url=".$url);
1857  }
1858 
1859  $mailfile = new CMailFile(
1860  $subject,
1861  $this->email,
1862  $conf->notification->email_from,
1863  $mesg,
1864  array(),
1865  array(),
1866  array(),
1867  '',
1868  '',
1869  0,
1870  $msgishtml
1871  );
1872 
1873  if ($mailfile->sendfile())
1874  {
1875  return 1;
1876  }
1877  else
1878  {
1879  $langs->trans("errors");
1880  $this->error=$langs->trans("ErrorFailedToSendPassword").' '.$mailfile->error;
1881  return -1;
1882  }
1883  }
1884 
1890  function error()
1891  {
1892  return $this->error;
1893  }
1894 
1895 
1902  {
1903  $sql = "SELECT url, login, pass, poste ";
1904  $sql.= " FROM ".MAIN_DB_PREFIX."user_clicktodial as u";
1905  $sql.= " WHERE u.fk_user = ".$this->id;
1906 
1907  $resql = $this->db->query($sql);
1908  if ($resql)
1909  {
1910  if ($this->db->num_rows($resql))
1911  {
1912  $obj = $this->db->fetch_object($resql);
1913 
1914  $this->clicktodial_url = $obj->url;
1915  $this->clicktodial_login = $obj->login;
1916  $this->clicktodial_password = $obj->pass;
1917  $this->clicktodial_poste = $obj->poste;
1918  }
1919 
1920  $this->clicktodial_loaded = 1; // Data loaded (found or not)
1921 
1922  $this->db->free($resql);
1923  return 1;
1924  }
1925  else
1926  {
1927  $this->error=$this->db->error();
1928  return -1;
1929  }
1930  }
1931 
1938  {
1939  $this->db->begin();
1940 
1941  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_clicktodial";
1942  $sql .= " WHERE fk_user = ".$this->id;
1943 
1944  dol_syslog(get_class($this).'::update_clicktodial', LOG_DEBUG);
1945  $result = $this->db->query($sql);
1946 
1947  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_clicktodial";
1948  $sql .= " (fk_user,url,login,pass,poste)";
1949  $sql .= " VALUES (".$this->id;
1950  $sql .= ", '". $this->db->escape($this->clicktodial_url) ."'";
1951  $sql .= ", '". $this->db->escape($this->clicktodial_login) ."'";
1952  $sql .= ", '". $this->db->escape($this->clicktodial_password) ."'";
1953  $sql .= ", '". $this->db->escape($this->clicktodial_poste) ."')";
1954 
1955  dol_syslog(get_class($this).'::update_clicktodial', LOG_DEBUG);
1956  $result = $this->db->query($sql);
1957  if ($result)
1958  {
1959  $this->db->commit();
1960  return 1;
1961  }
1962  else
1963  {
1964  $this->db->rollback();
1965  $this->error=$this->db->lasterror();
1966  return -1;
1967  }
1968  }
1969 
1970 
1979  function SetInGroup($group, $entity, $notrigger=0)
1980  {
1981  global $conf, $langs, $user;
1982 
1983  $error=0;
1984 
1985  $this->db->begin();
1986 
1987  $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user";
1988  $sql.= " WHERE fk_user = ".$this->id;
1989  $sql.= " AND fk_usergroup = ".$group;
1990  $sql.= " AND entity = ".$entity;
1991 
1992  $result = $this->db->query($sql);
1993 
1994  $sql = "INSERT INTO ".MAIN_DB_PREFIX."usergroup_user (entity, fk_user, fk_usergroup)";
1995  $sql.= " VALUES (".$entity.",".$this->id.",".$group.")";
1996 
1997  $result = $this->db->query($sql);
1998  if ($result)
1999  {
2000  if (! $error && ! $notrigger)
2001  {
2002  $this->newgroupid=$group; // deprecated. Remove this.
2003  $this->context = array('audit'=>$langs->trans("UserSetInGroup"), 'newgroupid'=>$group);
2004 
2005  // Call trigger
2006  $result=$this->call_trigger('USER_MODIFY',$user);
2007  if ($result < 0) { $error++; }
2008  // End call triggers
2009  }
2010 
2011  if (! $error)
2012  {
2013  $this->db->commit();
2014  return 1;
2015  }
2016  else
2017  {
2018  dol_syslog(get_class($this)."::SetInGroup ".$this->error, LOG_ERR);
2019  $this->db->rollback();
2020  return -2;
2021  }
2022  }
2023  else
2024  {
2025  $this->error=$this->db->lasterror();
2026  $this->db->rollback();
2027  return -1;
2028  }
2029  }
2030 
2039  function RemoveFromGroup($group, $entity, $notrigger=0)
2040  {
2041  global $conf,$langs,$user;
2042 
2043  $error=0;
2044 
2045  $this->db->begin();
2046 
2047  $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user";
2048  $sql.= " WHERE fk_user = ".$this->id;
2049  $sql.= " AND fk_usergroup = ".$group;
2050  $sql.= " AND entity = ".$entity;
2051 
2052  $result = $this->db->query($sql);
2053  if ($result)
2054  {
2055  if (! $error && ! $notrigger)
2056  {
2057  $this->oldgroupid=$group; // deprecated. Remove this.
2058  $this->context = array('audit'=>$langs->trans("UserRemovedFromGroup"), 'oldgroupid'=>$group);
2059 
2060  // Call trigger
2061  $result=$this->call_trigger('USER_MODIFY',$user);
2062  if ($result < 0) { $error++; }
2063  // End call triggers
2064  }
2065 
2066  if (! $error)
2067  {
2068  $this->db->commit();
2069  return 1;
2070  }
2071  else
2072  {
2073  $this->error=$interface->error;
2074  dol_syslog(get_class($this)."::RemoveFromGroup ".$this->error, LOG_ERR);
2075  $this->db->rollback();
2076  return -2;
2077  }
2078  }
2079  else
2080  {
2081  $this->error=$this->db->lasterror();
2082  $this->db->rollback();
2083  return -1;
2084  }
2085  }
2086 
2087 
2098  function getPhotoUrl($width, $height, $cssclass='', $imagesize='')
2099  {
2100  $result='';
2101 
2102  $result.='<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
2103  $result.=Form::showphoto('userphoto', $this, $width, $height, 0, $cssclass, $imagesize);
2104  $result.='</a>';
2105 
2106  return $result;
2107  }
2108 
2124  function getNomUrl($withpictoimg=0, $option='', $infologin=0, $notooltip=0, $maxlen=24, $hidethirdpartylogo=0, $mode='',$morecss='', $save_lastsearch_value=-1)
2125  {
2126  global $langs, $conf, $db, $hookmanager;
2127  global $dolibarr_main_authentication, $dolibarr_main_demo;
2128  global $menumanager;
2129 
2130  if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
2131 
2132  $result=''; $label='';
2133  $link=''; $linkstart=''; $linkend='';
2134 
2135  if (! empty($this->photo))
2136  {
2137  $label.= '<div class="photointooltip">';
2138  $label.= Form::showphoto('userphoto', $this, 0, 60, 0, 'photowithmargin photologintooltip', 'small', 0, 1); // Force height to 60 so we total height of tooltip can be calculated and collision can be managed
2139  $label.= '</div><div style="clear: both;"></div>';
2140  }
2141 
2142  $label.= '<div class="centpercent">';
2143  $label.= '<u>' . $langs->trans("User") . '</u><br>';
2144  $label.= '<b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs,'');
2145  if (! empty($this->login))
2146  $label.= '<br><b>' . $langs->trans('Login') . ':</b> ' . $this->login;
2147  $label.= '<br><b>' . $langs->trans("EMail").':</b> '.$this->email;
2148  if (! empty($this->admin))
2149  $label.= '<br><b>' . $langs->trans("Administrator").'</b>: '.yn($this->admin);
2150  if (! empty($this->societe_id) ) // Add thirdparty for external users
2151  {
2152  $thirdpartystatic = new Societe($db);
2153  $thirdpartystatic->fetch($this->societe_id);
2154  if (empty($hidethirdpartylogo)) $companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink')?'nolink':'')); // picto only of company
2155  $company=' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')';
2156  }
2157  $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal"));
2158  $label.= '<br><b>' . $langs->trans("Type") . ':</b> ' . $type;
2159  $label.= '<br><b>' . $langs->trans("Status").'</b>: '.$this->getLibStatut(0);
2160  $label.='</div>';
2161 
2162  // Info Login
2163  if ($infologin)
2164  {
2165  $label.= '<br>';
2166  $label.= '<br><u>'.$langs->trans("Connection").'</u>';
2167  $label.= '<br><b>'.$langs->trans("IPAddress").'</b>: '.$_SERVER["REMOTE_ADDR"];
2168  if (! empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $label.= '<br><b>'.$langs->trans("ConnectedOnMultiCompany").':</b> '.$conf->entity.' (user entity '.$this->entity.')';
2169  $label.= '<br><b>'.$langs->trans("AuthenticationMode").':</b> '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo)?'':' (demo)');
2170  $label.= '<br><b>'.$langs->trans("ConnectedSince").':</b> '.dol_print_date($this->datelastlogin,"dayhour",'tzuser');
2171  $label.= '<br><b>'.$langs->trans("PreviousConnexion").':</b> '.dol_print_date($this->datepreviouslogin,"dayhour",'tzuser');
2172  $label.= '<br><b>'.$langs->trans("CurrentTheme").':</b> '.$conf->theme;
2173  $label.= '<br><b>'.$langs->trans("CurrentMenuManager").':</b> '.$menumanager->name;
2174  $s=picto_from_langcode($langs->getDefaultLang());
2175  $label.= '<br><b>'.$langs->trans("CurrentUserLanguage").':</b> '.($s?$s.' ':'').$langs->getDefaultLang();
2176  $label.= '<br><b>'.$langs->trans("Browser").':</b> '.$conf->browser->name.($conf->browser->version?' '.$conf->browser->version:'').' ('.$_SERVER['HTTP_USER_AGENT'].')';
2177  $label.= '<br><b>'.$langs->trans("Layout").':</b> '.$conf->browser->layout;
2178  $label.= '<br><b>'.$langs->trans("Screen").':</b> '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight'];
2179  if (! empty($conf->browser->phone)) $label.= '<br><b>'.$langs->trans("Phone").':</b> '.$conf->browser->phone;
2180  if (! empty($_SESSION["disablemodules"])) $label.= '<br><b>'.$langs->trans("DisabledModules").':</b> <br>'.join(', ',explode(',',$_SESSION["disablemodules"]));
2181  }
2182 
2183  $url = DOL_URL_ROOT.'/user/card.php?id='.$this->id;
2184  if ($option == 'leave') $url = DOL_URL_ROOT.'/holiday/list.php?id='.$this->id;
2185 
2186  if ($option != 'nolink')
2187  {
2188  // Add param to save lastsearch_values or not
2189  $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
2190  if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
2191  if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
2192  }
2193 
2194  $linkstart='<a href="'.$url.'"';
2195  $linkclose="";
2196  if (empty($notooltip))
2197  {
2198  if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
2199  {
2200  $langs->load("users");
2201  $label=$langs->trans("ShowUser");
2202  $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
2203  }
2204  $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
2205  $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
2206  }
2207  if (! is_object($hookmanager))
2208  {
2209  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
2210  $hookmanager=new HookManager($this->db);
2211  }
2212  $hookmanager->initHooks(array('userdao'));
2213  $parameters=array('id'=>$this->id);
2214  $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
2215  if ($reshook > 0) $linkclose = $hookmanager->resPrint;
2216 
2217  $linkstart.=$linkclose.'>';
2218  $linkend='</a>';
2219 
2220  //if ($withpictoimg == -1) $result.='<div class="nowrap">';
2221  $result.=(($option == 'nolink')?'':$linkstart);
2222  if ($withpictoimg)
2223  {
2224  $paddafterimage='';
2225  if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"';
2226  // Only picto
2227  if ($withpictoimg > 0) $picto='<!-- picto user --><div class="inline-block nopadding '.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>';
2228  // Picto must be a photo
2229  else $picto='<!-- picto photo user --><div class="inline-block nopadding '.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>';
2230  $result.=$picto;
2231  }
2232  if ($withpictoimg > -2 && $withpictoimg != 2)
2233  {
2234  if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<div class="inline-block nopadding valignmiddle'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' usertext'.$morecss:'').'">';
2235  if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen);
2236  else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen);
2237  if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</div>';
2238  }
2239  $result.=(($option == 'nolink')?'':$linkend);
2240  //if ($withpictoimg == -1) $result.='</div>';
2241 
2242  $result.=$companylink;
2243 
2244  return $result;
2245  }
2246 
2254  function getLoginUrl($withpicto=0,$option='')
2255  {
2256  global $langs;
2257 
2258  $result='';
2259 
2260  $linkstart = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
2261  $linkend='</a>';
2262 
2263  if ($option == 'xxx')
2264  {
2265  $linkstart = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
2266  $linkend='</a>';
2267  }
2268 
2269  $result.=$linkstart;
2270  if ($withpicto) $result.=img_object($langs->trans("ShowUser"), 'user', 'class="paddingright"');
2271  $result.=$this->login;
2272  $result.=$linkend;
2273  return $result;
2274  }
2275 
2282  function getLibStatut($mode=0)
2283  {
2284  return $this->LibStatut($this->statut,$mode);
2285  }
2286 
2294  function LibStatut($statut,$mode=0)
2295  {
2296  global $langs;
2297  $langs->load('users');
2298 
2299  if ($mode == 0)
2300  {
2301  $prefix='';
2302  if ($statut == 1) return $langs->trans('Enabled');
2303  if ($statut == 0) return $langs->trans('Disabled');
2304  }
2305  if ($mode == 1)
2306  {
2307  if ($statut == 1) return $langs->trans('Enabled');
2308  if ($statut == 0) return $langs->trans('Disabled');
2309  }
2310  if ($mode == 2)
2311  {
2312  if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
2313  if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
2314  }
2315  if ($mode == 3)
2316  {
2317  if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
2318  if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
2319  }
2320  if ($mode == 4)
2321  {
2322  if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
2323  if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
2324  }
2325  if ($mode == 5)
2326  {
2327  if ($statut == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
2328  if ($statut == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
2329  }
2330  }
2331 
2332 
2342  function _load_ldap_dn($info,$mode=0)
2343  {
2344  global $conf;
2345  $dn='';
2346  if ($mode==0) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS].",".$conf->global->LDAP_USER_DN;
2347  if ($mode==1) $dn=$conf->global->LDAP_USER_DN;
2348  if ($mode==2) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS];
2349  return $dn;
2350  }
2351 
2357  function _load_ldap_info()
2358  {
2359  global $conf,$langs;
2360 
2361  $info=array();
2362  $keymodified=false;
2363 
2364  // Object classes
2365  $info["objectclass"]=explode(',',$conf->global->LDAP_USER_OBJECT_CLASS);
2366 
2367  $this->fullname=$this->getFullName($langs);
2368 
2369  // Possible LDAP KEY (constname => varname)
2370  $ldapkey = array(
2371  'LDAP_FIELD_FULLNAME' => 'fullname',
2372  'LDAP_FIELD_NAME' => 'lastname',
2373  'LDAP_FIELD_FIRSTNAME' => 'firstname',
2374  'LDAP_FIELD_LOGIN' => 'login',
2375  'LDAP_FIELD_LOGIN_SAMBA' => 'login',
2376  'LDAP_FIELD_PHONE' => 'office_phone',
2377  'LDAP_FIELD_MOBILE' => 'user_mobile',
2378  'LDAP_FIELD_FAX' => 'office_fax',
2379  'LDAP_FIELD_MAIL' => 'email',
2380  'LDAP_FIELD_SID' => 'ldap_sid',
2381  'LDAP_FIELD_SKYPE' => 'skype'
2382  );
2383 
2384  // Champs
2385  foreach ($ldapkey as $constname => $varname)
2386  {
2387  if (! empty($this->$varname) && ! empty($conf->global->$constname))
2388  {
2389  $info[$conf->global->$constname] = $this->$varname;
2390 
2391  // Check if it is the LDAP key and if its value has been changed
2392  if (! empty($conf->global->LDAP_KEY_USERS) && $conf->global->LDAP_KEY_USERS == $conf->global->$constname)
2393  {
2394  if (! empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) $keymodified=true; // For check if LDAP key has been modified
2395  }
2396  }
2397  }
2398  if ($this->address && ! empty($conf->global->LDAP_FIELD_ADDRESS)) $info[$conf->global->LDAP_FIELD_ADDRESS] = $this->address;
2399  if ($this->zip && ! empty($conf->global->LDAP_FIELD_ZIP)) $info[$conf->global->LDAP_FIELD_ZIP] = $this->zip;
2400  if ($this->town && ! empty($conf->global->LDAP_FIELD_TOWN)) $info[$conf->global->LDAP_FIELD_TOWN] = $this->town;
2401  if ($this->note_public && ! empty($conf->global->LDAP_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_FIELD_DESCRIPTION] = $this->note_public;
2402  if ($this->socid > 0)
2403  {
2404  $soc = new Societe($this->db);
2405  $soc->fetch($this->socid);
2406 
2407  $info[$conf->global->LDAP_FIELD_COMPANY] = $soc->name;
2408  if ($soc->client == 1) $info["businessCategory"] = "Customers";
2409  if ($soc->client == 2) $info["businessCategory"] = "Prospects";
2410  if ($soc->fournisseur == 1) $info["businessCategory"] = "Suppliers";
2411  }
2412 
2413  // When password is modified
2414  if (! empty($this->pass))
2415  {
2416  if (! empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte
2417  if (! empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // Create OpenLDAP MD5 password (TODO add type of encryption)
2418  }
2419  // Set LDAP password if possible
2420  else if ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2421  {
2422  if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
2423  {
2424  // Just for the default MD5 !
2425  if (empty($conf->global->MAIN_SECURITY_HASH_ALGO))
2426  {
2427  if ($this->pass_indatabase_crypted && ! empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) {
2428  $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase_crypted, 5); // Create OpenLDAP MD5 password from Dolibarr MD5 password
2429  }
2430  }
2431  }
2432  // Use $this->pass_indatabase value if exists
2433  else if (! empty($this->pass_indatabase))
2434  {
2435  if (! empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass_indatabase; // $this->pass_indatabase = mot de passe non crypte
2436  if (! empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase, 4); // md5 for OpenLdap TODO add type of encryption
2437  }
2438  }
2439 
2440  if ($conf->global->LDAP_SERVER_TYPE == 'egroupware')
2441  {
2442  $info["objectclass"][4] = "phpgwContact"; // compatibilite egroupware
2443 
2444  $info['uidnumber'] = $this->id;
2445 
2446  $info['phpgwTz'] = 0;
2447  $info['phpgwMailType'] = 'INTERNET';
2448  $info['phpgwMailHomeType'] = 'INTERNET';
2449 
2450  $info["phpgwContactTypeId"] = 'n';
2451  $info["phpgwContactCatId"] = 0;
2452  $info["phpgwContactAccess"] = "public";
2453 
2454  if (dol_strlen($this->egroupware_id) == 0)
2455  {
2456  $this->egroupware_id = 1;
2457  }
2458 
2459  $info["phpgwContactOwner"] = $this->egroupware_id;
2460 
2461  if ($this->email) $info["rfc822Mailbox"] = $this->email;
2462  if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile;
2463  }
2464 
2465  return $info;
2466  }
2467 
2468 
2476  function initAsSpecimen()
2477  {
2478  global $user,$langs;
2479 
2480  $now=dol_now();
2481 
2482  // Initialise parametres
2483  $this->id=0;
2484  $this->ref = 'SPECIMEN';
2485  $this->specimen=1;
2486 
2487  $this->lastname='DOLIBARR';
2488  $this->firstname='SPECIMEN';
2489  $this->gender='man';
2490  $this->note='This is a note';
2491  $this->email='email@specimen.com';
2492  $this->skype='tom.hanson';
2493  $this->office_phone='0999999999';
2494  $this->office_fax='0999999998';
2495  $this->user_mobile='0999999997';
2496  $this->admin=0;
2497  $this->login='dolibspec';
2498  $this->pass='dolibspec';
2499  //$this->pass_indatabase='dolibspec'; Set after a fetch
2500  //$this->pass_indatabase_crypted='e80ca5a88c892b0aaaf7e154853bccab'; Set after a fetch
2501  $this->datec=$now;
2502  $this->datem=$now;
2503 
2504  $this->datelastlogin=$now;
2505  $this->datepreviouslogin=$now;
2506  $this->statut=1;
2507 
2508  //$this->societe_id = 1; For external users
2509  //$this->contact_id = 1; For external users
2510  $this->entity = 1;
2511  }
2512 
2519  function info($id)
2520  {
2521  $sql = "SELECT u.rowid, u.login as ref, u.datec,";
2522  $sql.= " u.tms as date_modification, u.entity";
2523  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
2524  $sql.= " WHERE u.rowid = ".$id;
2525 
2526  $result=$this->db->query($sql);
2527  if ($result)
2528  {
2529  if ($this->db->num_rows($result))
2530  {
2531  $obj = $this->db->fetch_object($result);
2532 
2533  $this->id = $obj->rowid;
2534 
2535  $this->ref = (! $obj->ref) ? $obj->rowid : $obj->ref;
2536  $this->date_creation = $this->db->jdate($obj->datec);
2537  $this->date_modification = $this->db->jdate($obj->date_modification);
2538  $this->entity = $obj->entity;
2539  }
2540 
2541  $this->db->free($result);
2542 
2543  }
2544  else
2545  {
2546  dol_print_error($this->db);
2547  }
2548  }
2549 
2550 
2556  function getNbOfEMailings()
2557  {
2558  $sql = "SELECT count(mc.email) as nb";
2559  $sql.= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
2560  $sql.= " WHERE mc.email = '".$this->db->escape($this->email)."'";
2561  $sql.= " AND mc.statut=1"; // -1 erreur, 0 non envoye, 1 envoye avec succes
2562  $resql=$this->db->query($sql);
2563  if ($resql)
2564  {
2565  $obj = $this->db->fetch_object($resql);
2566  $nb=$obj->nb;
2567 
2568  $this->db->free($resql);
2569  return $nb;
2570  }
2571  else
2572  {
2573  $this->error=$this->db->error();
2574  return -1;
2575  }
2576  }
2577 
2586  function getNbOfUsers($limitTo, $option='', $admin=-1)
2587  {
2588  global $conf;
2589 
2590  $sql = "SELECT count(rowid) as nb";
2591  $sql.= " FROM ".MAIN_DB_PREFIX."user";
2592  if ($option == 'superadmin')
2593  {
2594  $sql.= " WHERE entity = 0";
2595  if ($admin >= 0) $sql.= " AND admin = ".$admin;
2596  }
2597  else
2598  {
2599  $sql.=" WHERE entity IN (".getEntity('user',0).")";
2600  if ($limitTo == 'active') $sql.= " AND statut = 1";
2601  if ($admin >= 0) $sql.= " AND admin = ".$admin;
2602  }
2603 
2604  $resql=$this->db->query($sql);
2605  if ($resql)
2606  {
2607  $obj = $this->db->fetch_object($resql);
2608  $nb=$obj->nb;
2609 
2610  $this->db->free($resql);
2611  return $nb;
2612  }
2613  else
2614  {
2615  $this->error=$this->db->lasterror();
2616  return -1;
2617  }
2618  }
2619 
2627  function update_ldap2dolibarr(&$ldapuser)
2628  {
2629  // TODO: Voir pourquoi le update met à jour avec toutes les valeurs vide (global $user écrase ?)
2630  global $user, $conf;
2631 
2632  $this->firstname=$ldapuser->{$conf->global->LDAP_FIELD_FIRSTNAME};
2633  $this->lastname=$ldapuser->{$conf->global->LDAP_FIELD_NAME};
2634  $this->login=$ldapuser->{$conf->global->LDAP_FIELD_LOGIN};
2635  $this->pass=$ldapuser->{$conf->global->LDAP_FIELD_PASSWORD};
2636  $this->pass_indatabase_crypted=$ldapuser->{$conf->global->LDAP_FIELD_PASSWORD_CRYPTED};
2637 
2638  $this->office_phone=$ldapuser->{$conf->global->LDAP_FIELD_PHONE};
2639  $this->user_mobile=$ldapuser->{$conf->global->LDAP_FIELD_MOBILE};
2640  $this->office_fax=$ldapuser->{$conf->global->LDAP_FIELD_FAX};
2641  $this->email=$ldapuser->{$conf->global->LDAP_FIELD_MAIL};
2642  $this->skype=$ldapuser->{$conf->global->LDAP_FIELD_SKYPE};
2643  $this->ldap_sid=$ldapuser->{$conf->global->LDAP_FIELD_SID};
2644 
2645  $this->job=$ldapuser->{$conf->global->LDAP_FIELD_TITLE};
2646  $this->note=$ldapuser->{$conf->global->LDAP_FIELD_DESCRIPTION};
2647 
2648  $result = $this->update($user);
2649 
2650  dol_syslog(get_class($this)."::update_ldap2dolibarr result=".$result, LOG_DEBUG);
2651 
2652  return $result;
2653  }
2654 
2655 
2662  function get_children()
2663  {
2664  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."user";
2665  $sql.= " WHERE fk_user = ".$this->id;
2666 
2667  dol_syslog(get_class($this)."::get_children result=".$result, LOG_DEBUG);
2668  $res = $this->db->query($sql);
2669  if ($res)
2670  {
2671  $users = array ();
2672  while ($rec = $this->db->fetch_array($res))
2673  {
2674  $user = new User($this->db);
2675  $user->fetch($rec['rowid']);
2676  $users[] = $user;
2677  }
2678  return $users;
2679  }
2680  else
2681  {
2682  dol_print_error($this->db);
2683  return -1;
2684  }
2685  }
2686 
2687 
2693  private function load_parentof()
2694  {
2695  global $conf;
2696 
2697  $this->parentof=array();
2698 
2699  // Load array[child]=parent
2700  $sql = "SELECT fk_user as id_parent, rowid as id_son";
2701  $sql.= " FROM ".MAIN_DB_PREFIX."user";
2702  $sql.= " WHERE fk_user <> 0";
2703  $sql.= " AND entity IN (".getEntity('user').")";
2704 
2705  dol_syslog(get_class($this)."::load_parentof", LOG_DEBUG);
2706  $resql = $this->db->query($sql);
2707  if ($resql)
2708  {
2709  while ($obj= $this->db->fetch_object($resql))
2710  {
2711  $this->parentof[$obj->id_son]=$obj->id_parent;
2712  }
2713  return 1;
2714  }
2715  else
2716  {
2717  dol_print_error($this->db);
2718  return -1;
2719  }
2720  }
2721 
2735  function get_full_tree($deleteafterid=0, $filter='')
2736  {
2737  global $conf,$user;
2738 
2739  $this->users = array();
2740 
2741  // Init this->parentof that is array(id_son=>id_parent, ...)
2742  $this->load_parentof();
2743 
2744  // Init $this->users array
2745  $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
2746  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
2747  if(! empty($conf->multicompany->enabled) && $conf->entity == 1 && (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) || (! empty($user->admin) && empty($user->entity))))
2748  {
2749  $sql.= " WHERE u.entity IS NOT NULL";
2750  }
2751  else
2752  {
2753  $sql.= " WHERE u.entity IN (".getEntity('user').")";
2754  }
2755  if ($filter) $sql.=" AND ".$filter;
2756 
2757  dol_syslog(get_class($this)."::get_full_tree get user list", LOG_DEBUG);
2758  $resql = $this->db->query($sql);
2759  if ($resql)
2760  {
2761  $i=0;
2762  while ($obj = $this->db->fetch_object($resql))
2763  {
2764  $this->users[$obj->rowid]['rowid'] = $obj->rowid;
2765  $this->users[$obj->rowid]['id'] = $obj->rowid;
2766  $this->users[$obj->rowid]['fk_user'] = $obj->fk_user;
2767  $this->users[$obj->rowid]['fk_soc'] = $obj->fk_soc;
2768  $this->users[$obj->rowid]['firstname'] = $obj->firstname;
2769  $this->users[$obj->rowid]['lastname'] = $obj->lastname;
2770  $this->users[$obj->rowid]['login'] = $obj->login;
2771  $this->users[$obj->rowid]['statut'] = $obj->statut;
2772  $this->users[$obj->rowid]['entity'] = $obj->entity;
2773  $this->users[$obj->rowid]['email'] = $obj->email;
2774  $this->users[$obj->rowid]['gender'] = $obj->gender;
2775  $this->users[$obj->rowid]['admin'] = $obj->admin;
2776  $this->users[$obj->rowid]['photo'] = $obj->photo;
2777  $i++;
2778  }
2779  }
2780  else
2781  {
2782  dol_print_error($this->db);
2783  return -1;
2784  }
2785 
2786  // We add the fullpath property to each elements of first level (no parent exists)
2787  dol_syslog(get_class($this)."::get_full_tree call to build_path_from_id_user", LOG_DEBUG);
2788  foreach($this->users as $key => $val)
2789  {
2790  $result = $this->build_path_from_id_user($key,0); // Process a branch from the root user key (this user has no parent)
2791  if ($result < 0)
2792  {
2793  $this->error='ErrorLoopInHierarchy';
2794  return -1;
2795  }
2796  }
2797 
2798  // Exclude leaf including $deleteafterid from tree
2799  if ($deleteafterid)
2800  {
2801  //print "Look to discard user ".$deleteafterid."\n";
2802  $keyfilter1='^'.$deleteafterid.'$';
2803  $keyfilter2='_'.$deleteafterid.'$';
2804  $keyfilter3='^'.$deleteafterid.'_';
2805  $keyfilter4='_'.$deleteafterid.'_';
2806  foreach($this->users as $key => $val)
2807  {
2808  if (preg_match('/'.$keyfilter1.'/',$val['fullpath']) || preg_match('/'.$keyfilter2.'/',$val['fullpath'])
2809  || preg_match('/'.$keyfilter3.'/',$val['fullpath']) || preg_match('/'.$keyfilter4.'/',$val['fullpath']))
2810  {
2811  unset($this->users[$key]);
2812  }
2813  }
2814  }
2815 
2816  dol_syslog(get_class($this)."::get_full_tree dol_sort_array", LOG_DEBUG);
2817  $this->users=dol_sort_array($this->users, 'fullname', 'asc', true, false);
2818 
2819  //var_dump($this->users);
2820 
2821  return $this->users;
2822  }
2823 
2832  function getAllChildIds($addcurrentuser=0)
2833  {
2834  $childids=array();
2835 
2836  if (isset($this->cache_childids[$this->id]))
2837  {
2838  $childids = $this->cache_childids[$this->id];
2839  }
2840  else
2841  {
2842  // Init this->users
2843  $this->get_full_tree();
2844 
2845  $idtoscan=$this->id;
2846 
2847  dol_syslog("Build childid for id = ".$idtoscan);
2848  foreach($this->users as $id => $val)
2849  {
2850  //var_dump($val['fullpath']);
2851  if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id'];
2852  }
2853  }
2854  $this->cache_childids[$this->id] = $childids;
2855 
2856  if ($addcurrentuser) $childids[$this->id]=$this->id;
2857 
2858  return $childids;
2859  }
2860 
2869  function build_path_from_id_user($id_user,$protection=0)
2870  {
2871  dol_syslog(get_class($this)."::build_path_from_id_user id_user=".$id_user." protection=".$protection, LOG_DEBUG);
2872 
2873  if (! empty($this->users[$id_user]['fullpath']))
2874  {
2875  // Already defined
2876  dol_syslog(get_class($this)."::build_path_from_id_user fullpath and fullname already defined", LOG_WARNING);
2877  return 0;
2878  }
2879 
2880  // Define fullpath and fullname
2881  $this->users[$id_user]['fullpath'] = '_'.$id_user;
2882  $this->users[$id_user]['fullname'] = $this->users[$id_user]['lastname'];
2883  $i=0; $cursor_user=$id_user;
2884 
2885  $useridfound=array($id_user);
2886  while (! empty($this->parentof[$cursor_user]))
2887  {
2888  if (in_array($this->parentof[$cursor_user], $useridfound))
2889  {
2890  dol_syslog("The hierarchy of user has a recursive loop", LOG_WARNING);
2891  return -1; // Should not happen. Protection against looping hierarchy
2892  }
2893  $useridfound[]=$this->parentof[$cursor_user];
2894  $this->users[$id_user]['fullpath'] = '_'.$this->parentof[$cursor_user].$this->users[$id_user]['fullpath'];
2895  $this->users[$id_user]['fullname'] = $this->users[$this->parentof[$cursor_user]]['lastname'].' >> '.$this->users[$id_user]['fullname'];
2896  $i++; $cursor_user=$this->parentof[$cursor_user];
2897  }
2898 
2899  // We count number of _ to have level
2900  $this->users[$id_user]['level']=dol_strlen(preg_replace('/[^_]/i','',$this->users[$id_user]['fullpath']));
2901 
2902  return 1;
2903  }
2904 
2913  public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
2914  {
2915  $tables = array(
2916  'user'
2917  );
2918 
2919  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
2920  }
2921 
2922 
2928  function load_state_board()
2929  {
2930  global $conf;
2931 
2932  $this->nb=array();
2933 
2934  $sql = "SELECT count(u.rowid) as nb";
2935  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
2936  $sql.= " WHERE u.statut > 0";
2937  //$sql.= " AND employee != 0";
2938  $sql.= " AND u.entity IN (".getEntity('user').")";
2939 
2940  $resql=$this->db->query($sql);
2941  if ($resql)
2942  {
2943  while ($obj=$this->db->fetch_object($resql))
2944  {
2945  $this->nb["users"]=$obj->nb;
2946  }
2947  $this->db->free($resql);
2948  return 1;
2949  }
2950  else
2951  {
2952  dol_print_error($this->db);
2953  $this->error=$this->db->error();
2954  return -1;
2955  }
2956  }
2957 
2968  public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
2969  {
2970  global $conf,$user,$langs;
2971 
2972  $langs->load("user");
2973 
2974  // Positionne le modele sur le nom du modele a utiliser
2975  if (! dol_strlen($modele))
2976  {
2977  if (! empty($conf->global->USER_ADDON_PDF))
2978  {
2979  $modele = $conf->global->USER_ADDON_PDF;
2980  }
2981  else
2982  {
2983  $modele = 'bluesky';
2984  }
2985  }
2986 
2987  $modelpath = "core/modules/user/doc/";
2988 
2989  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
2990  }
2991 
2992 }
2993 
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
get_full_tree($deleteafterid=0, $filter='')
Reconstruit l'arborescence hierarchique des users sous la forme d'un tableau Set and return this->use...
__construct($db)
Constructor de la classe.
Definition: user.class.php:143
SetInGroup($group, $entity, $notrigger=0)
Add user into a group.
_load_ldap_info()
Initialize the info array (array of LDAP values) that will be used to call LDAP functions.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it's its name (generic function)
setPassword($user, $password='', $changelater=0, $notrigger=0, $nosyncmember=0)
Change password of a user.
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
create($user, $notrigger=0)
Create a user into database.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '...' if string larger than length.
update_ldap2dolibarr(&$ldapuser)
Update user using data from the LDAP.
getLibStatut($mode=0)
Return label of status of user (active, inactive)
update($user, $notrigger=0, $nosyncmember=0, $nosyncmemberpass=0, $nosynccontact=0)
Update a user into database (and also password if this->pass is defined)
conf($dolibarr_main_document_root)
Load conf file (file must exists)
Definition: inc.php:282
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
Class to manage contact/addresses.
getAllChildIds($addcurrentuser=0)
Return list of all child users id in herarchy (all sublevels).
set_default_rights()
Assign rights by default.
getNomUrl($withpictoimg=0, $option='', $infologin=0, $notooltip=0, $maxlen=24, $hidethirdpartylogo=0, $mode='', $morecss='', $save_lastsearch_value=-1)
Return a link to the user card (with optionaly the picto) Use this->id,this->lastname, this->firstname.
Class to manage Dolibarr users.
Definition: user.class.php:39
Class to manage Dolibarr database access.
update_clicktodial()
Update clicktodial info.
static showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0)
Return HTML code to output a photo.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
getFullName($langs, $option=0, $nameorder=-1, $maxlen=0)
Return full name (civility+' '+name+' '+lastname)
get_children()
Return and array with all instanciated first level children users of current user.
load_parentof()
Load this->parentof that is array(id_son=>id_parent, ...)
$contact_id
Definition: user.class.php:91
fetch_clicktodial()
Read clicktodial information for user.
delrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0)
Remove a right to the user.
Definition: user.class.php:556
info($id)
Load info of user object.
getNbOfUsers($limitTo, $option='', $admin=-1)
Return number of existing users.
Class to manage standard extra fields.
Class to manage hooks.
setstatus($statut)
Change status of a user.
Definition: user.class.php:833
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
load_state_board()
Charge indicateurs this->nb pour le tableau de bord.
RemoveFromGroup($group, $entity, $notrigger=0)
Remove a user from a group.
Class to manage third parties objects (customers, suppliers, prospects...)
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
initAsSpecimen()
Initialise an instance with random values.
Class to manage categories.
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to,$css,$trackid,$moreinheader,$sendcontext); $mailfile->sendfile();.
static commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
Class to manage members of a foundation.
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
deleteExtraFields()
Delete all extra fields values for the current object.
Class to manage translations.
$pass_indatabase_crypted
Encrypted password in database (always defined)
Definition: user.class.php:76
dol_now($mode='gmt')
Return date for now.
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
getRandomPassword($generic=false)
Return a generated password using default module.
_load_ldap_dn($info, $mode=0)
Retourne chaine DN complete dans l'annuaire LDAP pour l'objet.
$societe_id
If this is defined, it is an external user.
Definition: user.class.php:86
setCategories($categories)
Sets object to supplied categories.
Definition: user.class.php:881
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
build_path_from_id_user($id_user, $protection=0)
For user id_user and its childs available in this->users, define property fullpath and fullname...
clearrights()
Clear all permissions array of user.
Definition: user.class.php:663
addrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0)
Add a right to the user.
Definition: user.class.php:438
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->societe->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1013
fetch($id='', $login='', $sid='', $loadpersonalconf=0, $entity=-1)
Load a user from database with its id or ref (login).
Definition: user.class.php:177
dol_hash($chain, $type='0')
Returns a hash of a string.
create_from_contact($contact, $login='', $password='')
Create a user from a contact object.
LibStatut($statut, $mode=0)
Renvoi le libelle d'un statut donne.
call_trigger($trigger_name, $user)
Call trigger based on this instance.
create_from_member($member, $login='')
Create a user into database from a member object.
$pass
Clear password in memory.
Definition: user.class.php:72
send_password($user, $password='', $changelater=0)
Send new password by email.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Create a document onto disk according to template module.
getNbOfEMailings()
Return number of mass Emailing received by this contacts with its email.
$pass_indatabase
Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
Definition: user.class.php:74
getrights($moduletag='')
Load permissions granted to user into object user.
Definition: user.class.php:679
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
update_last_login_date()
Mise a jour en base de la date de derniere connexion d'un utilisateur Fonction appelee lors d'une nou...
getPhotoUrl($width, $height, $cssclass='', $imagesize='')
Return a link with photo Use this->id,this->photo.
picto_from_langcode($codelang, $moreatt= '')
Return img flag of country for a language code or country code.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
getLoginUrl($withpicto=0, $option='')
Return clickable link of login (eventualy with picto)
error()
Renvoie la derniere erreur fonctionnelle de manipulation de l'objet.
Class to manage warehouses.