dolibarr  9.0.0
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@inodbox.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-2018 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  * Copyright (C) 2018 charlene Benke <charlie@patas-monkey.com>
14  * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program. If not, see <http://www.gnu.org/licenses/>.
28  */
29 
36 require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
37 
41 class User extends CommonObject
42 {
46  public $element='user';
47 
51  public $table_element='user';
52 
56  public $fk_element='fk_user';
57 
62  public $ismultientitymanaged = 1;
63 
64  public $id=0;
65  public $statut;
66  public $ldap_sid;
67  public $search_sid;
68  public $employee;
69  public $gender;
70  public $birth;
71  public $email;
72 
73  public $skype;
74  public $twitter;
75  public $facebook;
76 
77  public $job; // job position
78  public $signature;
79 
83  public $address;
84 
85  public $zip;
86  public $town;
87  public $state_id; // The state/department
88  public $state_code;
89  public $state;
90  public $office_phone;
91  public $office_fax;
92  public $user_mobile;
93  public $admin;
94  public $login;
95  public $api_key;
96 
100  public $entity;
101 
103  public $pass;
108 
109  public $datec;
110  public $datem;
111 
113 
117  public $societe_id;
122  public $contact_id;
123  public $socid;
124  public $contactid;
125 
129  public $fk_member;
130 
134  public $fk_user;
135 
136  public $clicktodial_url;
137  public $clicktodial_login;
138  public $clicktodial_password;
139  public $clicktodial_poste;
140 
141  public $datelastlogin;
142  public $datepreviouslogin;
143  public $photo;
144  public $lang;
145 
146  public $rights; // Array of permissions user->rights->permx
147  public $all_permissions_are_loaded; // All permission are loaded
148  public $nb_rights; // Number of rights granted to the user
149  private $_tab_loaded=array(); // Cache array of already loaded permissions
150 
151  public $conf; // To store personal config
152  public $default_values; // To store default values for user
153  public $lastsearch_values_tmp; // To store current search criterias for user
154  public $lastsearch_values; // To store last saved search criterias for user
155 
156  public $users = array(); // To store all tree of users hierarchy
157  public $parentof; // To store an array of all parents for all ids.
158  private $cache_childids;
159 
160  public $accountancy_code; // Accountancy code in prevision of the complete accountancy module
161 
162  public $thm; // Average cost of employee - Used for valuation of time spent
163  public $tjm; // Average cost of employee
164 
165  public $salary; // Monthly salary - Denormalized value from llx_user_employment
166  public $salaryextra; // Monthly salary extra - Denormalized value from llx_user_employment
167  public $weeklyhours; // Weekly hours - Denormalized value from llx_user_employment
168 
169  public $color; // Define background color for user in agenda
170 
171  public $dateemployment; // Define date of employment by company
172  public $dateemploymentend; // Define date of employment end by company
173 
174  public $default_c_exp_tax_cat;
175  public $default_range;
176 
177  public $fields = array(
178  'rowid'=>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'),
179  'lastname'=>array('type'=>'varchar(50)', 'label'=>'Name', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1, 'comment'=>'Reference of object'),
180  'firstname'=>array('type'=>'varchar(50)', 'label'=>'Name','enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
181  );
182 
188  function __construct($db)
189  {
190  $this->db = $db;
191 
192  // User preference
193  $this->liste_limit = 0;
194  $this->clicktodial_loaded = 0;
195 
196  // For cache usage
197  $this->all_permissions_are_loaded = 0;
198  $this->nb_rights = 0;
199 
200  // Force some default values
201  $this->admin = 0;
202  $this->employee = 1;
203 
204  $this->conf = new stdClass();
205  $this->rights = new stdClass();
206  $this->rights->user = new stdClass();
207  $this->rights->user->user = new stdClass();
208  $this->rights->user->self = new stdClass();
209  }
210 
222  function fetch($id='', $login='', $sid='', $loadpersonalconf=0, $entity=-1)
223  {
224  global $conf, $user;
225 
226  // Clean parameters
227  $login=trim($login);
228 
229  // Get user
230  $sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.twitter, u.facebook,";
231  $sql.= " u.signature, u.office_phone, u.office_fax, u.user_mobile,";
232  $sql.= " u.address, u.zip, u.town, u.fk_state as state_id, u.fk_country as country_id,";
233  $sql.= " u.admin, u.login, u.note,";
234  $sql.= " u.pass, u.pass_crypted, u.pass_temp, u.api_key,";
235  $sql.= " u.fk_soc, u.fk_socpeople, u.fk_member, u.fk_user, u.ldap_sid,";
236  $sql.= " u.statut, u.lang, u.entity,";
237  $sql.= " u.datec as datec,";
238  $sql.= " u.tms as datem,";
239  $sql.= " u.datelastlogin as datel,";
240  $sql.= " u.datepreviouslogin as datep,";
241  $sql.= " u.photo as photo,";
242  $sql.= " u.openid as openid,";
243  $sql.= " u.accountancy_code,";
244  $sql.= " u.thm,";
245  $sql.= " u.tjm,";
246  $sql.= " u.salary,";
247  $sql.= " u.salaryextra,";
248  $sql.= " u.weeklyhours,";
249  $sql.= " u.color,";
250  $sql.= " u.dateemployment, u.dateemploymentend,";
251  $sql.= " u.ref_int, u.ref_ext,";
252  $sql.= " u.default_range, u.default_c_exp_tax_cat,"; // Expense report default mode
253  $sql.= " c.code as country_code, c.label as country,";
254  $sql.= " d.code_departement as state_code, d.nom as state";
255  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
256  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON u.fk_country = c.rowid";
257  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON u.fk_state = d.rowid";
258 
259  if ($entity < 0)
260  {
261  if ((empty($conf->multicompany->enabled) || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) && (! empty($user->entity)))
262  {
263  $sql.= " WHERE u.entity IN (0,".$conf->entity.")";
264  }
265  else
266  {
267  $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
268  }
269  }
270  else // The fetch was forced on an entity
271  {
272  if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
273  $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
274  else
275  $sql.= " WHERE u.entity IN (0, ".(($entity!='' && $entity >= 0)?$entity:$conf->entity).")"; // search in entity provided in parameter
276  }
277 
278  if ($sid) // permet une recherche du user par son SID ActiveDirectory ou Samba
279  {
280  $sql.= " AND (u.ldap_sid = '".$this->db->escape($sid)."' OR u.login = '".$this->db->escape($login)."') LIMIT 1";
281  }
282  else if ($login)
283  {
284  $sql.= " AND u.login = '".$this->db->escape($login)."'";
285  }
286  else
287  {
288  $sql.= " AND u.rowid = ".$id;
289  }
290  $sql.= " ORDER BY u.entity ASC"; // Avoid random result when there is 2 login in 2 different entities
291 
292  $result = $this->db->query($sql);
293  if ($result)
294  {
295  $obj = $this->db->fetch_object($result);
296  if ($obj)
297  {
298  $this->id = $obj->rowid;
299  $this->ref = $obj->rowid;
300 
301  $this->ref_int = $obj->ref_int;
302  $this->ref_ext = $obj->ref_ext;
303 
304  $this->ldap_sid = $obj->ldap_sid;
305  $this->lastname = $obj->lastname;
306  $this->firstname = $obj->firstname;
307 
308  $this->employee = $obj->employee;
309 
310  $this->login = $obj->login;
311  $this->gender = $obj->gender;
312  $this->birth = $this->db->jdate($obj->birth);
313  $this->pass_indatabase = $obj->pass;
314  $this->pass_indatabase_crypted = $obj->pass_crypted;
315  $this->pass = $obj->pass;
316  $this->pass_temp = $obj->pass_temp;
317  $this->api_key = $obj->api_key;
318 
319  $this->address = $obj->address;
320  $this->zip = $obj->zip;
321  $this->town = $obj->town;
322 
323  $this->country_id = $obj->country_id;
324  $this->country_code = $obj->country_id?$obj->country_code:'';
325  //$this->country = $obj->country_id?($langs->trans('Country'.$obj->country_code)!='Country'.$obj->country_code?$langs->transnoentities('Country'.$obj->country_code):$obj->country):'';
326 
327  $this->state_id = $obj->state_id;
328  $this->state_code = $obj->state_code;
329  $this->state = ($obj->state!='-'?$obj->state:'');
330 
331  $this->office_phone = $obj->office_phone;
332  $this->office_fax = $obj->office_fax;
333  $this->user_mobile = $obj->user_mobile;
334  $this->email = $obj->email;
335  $this->skype = $obj->skype;
336  $this->twitter = $obj->twitter;
337  $this->facebook = $obj->facebook;
338  $this->job = $obj->job;
339  $this->signature = $obj->signature;
340  $this->admin = $obj->admin;
341  $this->note = $obj->note;
342  $this->statut = $obj->statut;
343  $this->photo = $obj->photo;
344  $this->openid = $obj->openid;
345  $this->lang = $obj->lang;
346  $this->entity = $obj->entity;
347  $this->accountancy_code = $obj->accountancy_code;
348  $this->thm = $obj->thm;
349  $this->tjm = $obj->tjm;
350  $this->salary = $obj->salary;
351  $this->salaryextra = $obj->salaryextra;
352  $this->weeklyhours = $obj->weeklyhours;
353  $this->color = $obj->color;
354  $this->dateemployment = $this->db->jdate($obj->dateemployment);
355  $this->dateemploymentend = $this->db->jdate($obj->dateemploymentend);
356 
357  $this->datec = $this->db->jdate($obj->datec);
358  $this->datem = $this->db->jdate($obj->datem);
359  $this->datelastlogin = $this->db->jdate($obj->datel);
360  $this->datepreviouslogin = $this->db->jdate($obj->datep);
361 
362  $this->societe_id = $obj->fk_soc; // deprecated
363  $this->contact_id = $obj->fk_socpeople; // deprecated
364  $this->socid = $obj->fk_soc;
365  $this->contactid = $obj->fk_socpeople;
366  $this->fk_member = $obj->fk_member;
367  $this->fk_user = $obj->fk_user;
368 
369  $this->default_range = $obj->default_range;
370  $this->default_c_exp_tax_cat = $obj->default_c_exp_tax_cat;
371 
372  // Protection when module multicompany was set, admin was set to first entity and then, the module was disabled,
373  // in such case, this admin user must be admin for ALL entities.
374  if (empty($conf->multicompany->enabled) && $this->admin && $this->entity == 1) $this->entity = 0;
375 
376  // Retreive all extrafield
377  // fetch optionals attributes and labels
378  $this->fetch_optionals();
379 
380  $this->db->free($result);
381  }
382  else
383  {
384  $this->error="USERNOTFOUND";
385  dol_syslog(get_class($this)."::fetch user not found", LOG_DEBUG);
386 
387  $this->db->free($result);
388  return 0;
389  }
390  }
391  else
392  {
393  $this->error=$this->db->lasterror();
394  return -1;
395  }
396 
397  // To get back the global configuration unique to the user
398  if ($loadpersonalconf)
399  {
400  // Load user->conf for user
401  $sql = "SELECT param, value FROM ".MAIN_DB_PREFIX."user_param";
402  $sql.= " WHERE fk_user = ".$this->id;
403  $sql.= " AND entity = ".$conf->entity;
404  //dol_syslog(get_class($this).'::fetch load personalized conf', LOG_DEBUG);
405  $resql=$this->db->query($sql);
406  if ($resql)
407  {
408  $num = $this->db->num_rows($resql);
409  $i = 0;
410  while ($i < $num)
411  {
412  $obj = $this->db->fetch_object($resql);
413  $p=(! empty($obj->param)?$obj->param:'');
414  if (! empty($p)) $this->conf->$p = $obj->value;
415  $i++;
416  }
417  $this->db->free($resql);
418  }
419  else
420  {
421  $this->error=$this->db->lasterror();
422  return -2;
423  }
424 
425  $result = $this->loadDefaultValues();
426 
427  if ($result < 0)
428  {
429  $this->error=$this->db->lasterror();
430  return -3;
431  }
432  }
433 
434  return 1;
435  }
436 
442  function loadDefaultValues()
443  {
444  global $conf;
445 
446  // Load user->default_values for user. TODO Save this in memcached ?
447  $sql = "SELECT rowid, entity, type, page, param, value";
448  $sql.= " FROM ".MAIN_DB_PREFIX."default_values";
449  $sql.= " WHERE entity IN (".($this->entity > 0 ? $this->entity.", " : "").$conf->entity.")"; // Entity of user (if defined) + current entity
450  $sql.= " AND user_id IN (0".($this->id > 0 ? ", ".$this->id : "").")"; // User 0 (all) + me (if defined)
451  $resql = $this->db->query($sql);
452  if ($resql)
453  {
454  while ($obj = $this->db->fetch_object($resql))
455  {
456  if (! empty($obj->page) && ! empty($obj->type) && ! empty($obj->param))
457  {
458  // $obj->page is relative URL with or without params
459  // $obj->type can be 'filters', 'sortorder', 'createform', ...
460  // $obj->param is key or param
461  $pagewithoutquerystring=$obj->page;
462  $pagequeries='';
463  if (preg_match('/^([^\?]+)\?(.*)$/', $pagewithoutquerystring, $reg)) // There is query param
464  {
465  $pagewithoutquerystring=$reg[1];
466  $pagequeries=$reg[2];
467  }
468  $this->default_values[$pagewithoutquerystring][$obj->type][$pagequeries?$pagequeries:'_noquery_'][$obj->param]=$obj->value;
469  //if ($pagequeries) $this->default_values[$pagewithoutquerystring][$obj->type.'_queries']=$pagequeries;
470  }
471  }
472  // Sort by key, so _noquery_ is last
473  if(!empty($this->default_values)) {
474  foreach($this->default_values as $a => $b)
475  {
476  foreach($b as $c => $d)
477  {
478  krsort($this->default_values[$a][$c]);
479  }
480  }
481  }
482  $this->db->free($resql);
483 
484  return 1;
485  }
486  else
487  {
488  dol_print_error($this->db);
489  return -1;
490  }
491  }
492 
504  function addrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0)
505  {
506  global $conf, $user, $langs;
507 
508  $entity = (! empty($entity)?$entity:$conf->entity);
509 
510  dol_syslog(get_class($this)."::addrights $rid, $allmodule, $allperms, $entity");
511  $error=0;
512  $whereforadd='';
513 
514  $this->db->begin();
515 
516  if (! empty($rid))
517  {
518  // Si on a demande ajout d'un droit en particulier, on recupere
519  // les caracteristiques (module, perms et subperms) de ce droit.
520  $sql = "SELECT module, perms, subperms";
521  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
522  $sql.= " WHERE id = '".$this->db->escape($rid)."'";
523  $sql.= " AND entity = ".$entity;
524 
525  $result=$this->db->query($sql);
526  if ($result) {
527  $obj = $this->db->fetch_object($result);
528  $module=$obj->module;
529  $perms=$obj->perms;
530  $subperms=$obj->subperms;
531  }
532  else {
533  $error++;
534  dol_print_error($this->db);
535  }
536 
537  // Where pour la liste des droits a ajouter
538  $whereforadd="id=".$this->db->escape($rid);
539  // Ajout des droits induits
540  if (! empty($subperms)) $whereforadd.=" OR (module='$module' AND perms='$perms' AND (subperms='lire' OR subperms='read'))";
541  else if (! empty($perms)) $whereforadd.=" OR (module='$module' AND (perms='lire' OR perms='read') AND subperms IS NULL)";
542  }
543  else {
544  // On a pas demande un droit en particulier mais une liste de droits
545  // sur la base d'un nom de module de de perms
546  // Where pour la liste des droits a ajouter
547  if (! empty($allmodule))
548  {
549  if ($allmodule == 'allmodules')
550  {
551  $whereforadd='allmodules';
552  }
553  else
554  {
555  $whereforadd="module='".$this->db->escape($allmodule)."'";
556  if (! empty($allperms)) $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
557  }
558  }
559  }
560 
561  // Ajout des droits trouves grace au critere whereforadd
562  if (! empty($whereforadd))
563  {
564  //print "$module-$perms-$subperms";
565  $sql = "SELECT id";
566  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
567  $sql.= " WHERE entity = ".$entity;
568  if (! empty($whereforadd) && $whereforadd != 'allmodules') {
569  $sql.= " AND ".$whereforadd;
570  }
571 
572  $result=$this->db->query($sql);
573  if ($result)
574  {
575  $num = $this->db->num_rows($result);
576  $i = 0;
577  while ($i < $num)
578  {
579  $obj = $this->db->fetch_object($result);
580  $nid = $obj->id;
581 
582  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id." AND fk_id=".$nid." AND entity = ".$entity;
583  if (! $this->db->query($sql)) $error++;
584  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (entity, fk_user, fk_id) VALUES (".$entity.", ".$this->id.", ".$nid.")";
585  if (! $this->db->query($sql)) $error++;
586 
587  $i++;
588  }
589  }
590  else
591  {
592  $error++;
593  dol_print_error($this->db);
594  }
595  }
596 
597  if (! $error && ! $notrigger)
598  {
599  $langs->load("other");
600  $this->context = array('audit'=>$langs->trans("PermissionsAdd").($rid?' (id='.$rid.')':''));
601 
602  // Call trigger
603  $result=$this->call_trigger('USER_MODIFY',$user);
604  if ($result < 0) { $error++; }
605  // End call triggers
606  }
607 
608  if ($error) {
609  $this->db->rollback();
610  return -$error;
611  }
612  else {
613  $this->db->commit();
614  return 1;
615  }
616  }
617 
618 
630  function delrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0)
631  {
632  global $conf, $user, $langs;
633 
634  $error=0;
635  $wherefordel='';
636  $entity = (! empty($entity)?$entity:$conf->entity);
637 
638  $this->db->begin();
639 
640  if (! empty($rid))
641  {
642  // Si on a demande supression d'un droit en particulier, on recupere
643  // les caracteristiques module, perms et subperms de ce droit.
644  $sql = "SELECT module, perms, subperms";
645  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
646  $sql.= " WHERE id = '".$this->db->escape($rid)."'";
647  $sql.= " AND entity = ".$entity;
648 
649  $result=$this->db->query($sql);
650  if ($result) {
651  $obj = $this->db->fetch_object($result);
652  $module=$obj->module;
653  $perms=$obj->perms;
654  $subperms=$obj->subperms;
655  }
656  else {
657  $error++;
658  dol_print_error($this->db);
659  }
660 
661  // Where pour la liste des droits a supprimer
662  $wherefordel="id=".$this->db->escape($rid);
663  // Suppression des droits induits
664  if ($subperms=='lire' || $subperms=='read') $wherefordel.=" OR (module='$module' AND perms='$perms' AND subperms IS NOT NULL)";
665  if ($perms=='lire' || $perms=='read') $wherefordel.=" OR (module='$module')";
666  }
667  else {
668  // On a demande suppression d'un droit sur la base d'un nom de module ou perms
669  // Where pour la liste des droits a supprimer
670  if (! empty($allmodule))
671  {
672  if ($allmodule == 'allmodules')
673  {
674  $wherefordel='allmodules';
675  }
676  else
677  {
678  $wherefordel="module='".$this->db->escape($allmodule)."'";
679  if (! empty($allperms)) $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
680  }
681  }
682  }
683 
684  // Suppression des droits selon critere defini dans wherefordel
685  if (! empty($wherefordel))
686  {
687  //print "$module-$perms-$subperms";
688  $sql = "SELECT id";
689  $sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
690  $sql.= " WHERE entity = ".$entity;
691  if (! empty($wherefordel) && $wherefordel != 'allmodules') {
692  $sql.= " AND ".$wherefordel;
693  }
694 
695  $result=$this->db->query($sql);
696  if ($result)
697  {
698  $num = $this->db->num_rows($result);
699  $i = 0;
700  while ($i < $num)
701  {
702  $obj = $this->db->fetch_object($result);
703  $nid = $obj->id;
704 
705  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights";
706  $sql.= " WHERE fk_user = ".$this->id." AND fk_id=".$nid;
707  $sql.= " AND entity = ".$entity;
708  if (! $this->db->query($sql)) $error++;
709 
710  $i++;
711  }
712  }
713  else
714  {
715  $error++;
716  dol_print_error($this->db);
717  }
718  }
719 
720  if (! $error && ! $notrigger)
721  {
722  $langs->load("other");
723  $this->context = array('audit'=>$langs->trans("PermissionsDelete").($rid?' (id='.$rid.')':''));
724 
725  // Call trigger
726  $result=$this->call_trigger('USER_MODIFY',$user);
727  if ($result < 0) { $error++; }
728  // End call triggers
729  }
730 
731  if ($error) {
732  $this->db->rollback();
733  return -$error;
734  }
735  else {
736  $this->db->commit();
737  return 1;
738  }
739  }
740 
741 
748  function clearrights()
749  {
750  dol_syslog(get_class($this)."::clearrights reset user->rights");
751  $this->rights='';
752  $this->all_permissions_are_loaded=false;
753  $this->_tab_loaded=array();
754  }
755 
756 
765  function getrights($moduletag='', $forcereload=0)
766  {
767  global $conf;
768 
769  if (empty($forcereload))
770  {
771  if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag])
772  {
773  // Rights for this module are already loaded, so we leave
774  return;
775  }
776 
777  if ($this->all_permissions_are_loaded)
778  {
779  // We already loaded all rights for this user, so we leave
780  return;
781  }
782  }
783 
784  // Recuperation des droits utilisateurs + recuperation des droits groupes
785 
786  // D'abord les droits utilisateurs
787  $sql = "SELECT DISTINCT r.module, r.perms, r.subperms";
788  $sql.= " FROM ".MAIN_DB_PREFIX."user_rights as ur";
789  $sql.= ", ".MAIN_DB_PREFIX."rights_def as r";
790  $sql.= " WHERE r.id = ur.fk_id";
791  if (! empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY))
792  {
793  $sql.= " AND r.entity IN (0,".(! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)?"1,":"").$conf->entity.")";
794  }
795  else
796  {
797  $sql.= " AND ur.entity = ".$conf->entity;
798  }
799  $sql.= " AND ur.fk_user= ".$this->id;
800  $sql.= " AND r.perms IS NOT NULL";
801  if ($moduletag) $sql.= " AND r.module = '".$this->db->escape($moduletag)."'";
802 
803  $resql = $this->db->query($sql);
804  if ($resql)
805  {
806  $num = $this->db->num_rows($resql);
807  $i = 0;
808  while ($i < $num)
809  {
810  $obj = $this->db->fetch_object($resql);
811 
812  $module=$obj->module;
813  $perms=$obj->perms;
814  $subperms=$obj->subperms;
815 
816  if ($perms)
817  {
818  if (! isset($this->rights) || ! is_object($this->rights)) $this->rights = new stdClass(); // For avoid error
819  if ($module)
820  {
821  if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
822  if ($subperms)
823  {
824  if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
825  if(empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++;
826  $this->rights->$module->$perms->$subperms = 1;
827  }
828  else
829  {
830  if(empty($this->rights->$module->$perms)) $this->nb_rights++;
831  $this->rights->$module->$perms = 1;
832  }
833  }
834  }
835  $i++;
836  }
837  $this->db->free($resql);
838  }
839 
840  // Maintenant les droits groupes
841  $sql = "SELECT DISTINCT r.module, r.perms, r.subperms";
842  $sql.= " FROM ".MAIN_DB_PREFIX."usergroup_rights as gr,";
843  $sql.= " ".MAIN_DB_PREFIX."usergroup_user as gu,";
844  $sql.= " ".MAIN_DB_PREFIX."rights_def as r";
845  $sql.= " WHERE r.id = gr.fk_id";
846  if (! empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY))
847  {
848  if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
849  $sql.= " AND gu.entity IN (0,".$conf->entity.")";
850  } else {
851  $sql.= " AND r.entity = ".$conf->entity;
852  }
853  }
854  else
855  {
856  $sql.= " AND gr.entity = ".$conf->entity;
857  $sql.= " AND r.entity = ".$conf->entity;
858  }
859  $sql.= " AND gr.fk_usergroup = gu.fk_usergroup";
860  $sql.= " AND gu.fk_user = ".$this->id;
861  $sql.= " AND r.perms IS NOT NULL";
862  if ($moduletag) $sql.= " AND r.module = '".$this->db->escape($moduletag)."'";
863 
864  $resql = $this->db->query($sql);
865  if ($resql)
866  {
867  $num = $this->db->num_rows($resql);
868  $i = 0;
869  while ($i < $num)
870  {
871  $obj = $this->db->fetch_object($resql);
872 
873  $module=$obj->module;
874  $perms=$obj->perms;
875  $subperms=$obj->subperms;
876 
877  if ($perms)
878  {
879  if (! isset($this->rights) || ! is_object($this->rights)) $this->rights = new stdClass(); // For avoid error
880  if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
881  if ($subperms)
882  {
883  if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
884  if(empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++;
885  $this->rights->$module->$perms->$subperms = 1;
886  }
887  else
888  {
889  if(empty($this->rights->$module->$perms)) $this->nb_rights++;
890  // if we have already define a subperm like this $this->rights->$module->level1->level2 with llx_user_rights, we don't want override level1 because the level2 can be not define on user group
891  if (!is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = 1;
892  }
893  }
894  $i++;
895  }
896  $this->db->free($resql);
897  }
898 
899  // For backward compatibility
900  if (isset($this->rights->propale) && ! isset($this->rights->propal)) $this->rights->propal = $this->rights->propale;
901  if (isset($this->rights->propal) && ! isset($this->rights->propale)) $this->rights->propale = $this->rights->propal;
902 
903  if (! $moduletag)
904  {
905  // Si module etait non defini, alors on a tout charge, on peut donc considerer
906  // que les droits sont en cache (car tous charges) pour cet instance de user
907  $this->all_permissions_are_loaded=1;
908  }
909  else
910  {
911  // Si module defini, on le marque comme charge en cache
912  $this->_tab_loaded[$moduletag]=1;
913  }
914  }
915 
922  function setstatus($statut)
923  {
924  global $conf,$langs,$user;
925 
926  $error=0;
927 
928  // Check parameters
929  if ($this->statut == $statut) return 0;
930  else $this->statut = $statut;
931 
932  $this->db->begin();
933 
934  // Deactivate user
935  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
936  $sql.= " SET statut = ".$this->statut;
937  $sql.= " WHERE rowid = ".$this->id;
938  $result = $this->db->query($sql);
939 
940  dol_syslog(get_class($this)."::setstatus", LOG_DEBUG);
941  if ($result)
942  {
943  // Call trigger
944  $result=$this->call_trigger('USER_ENABLEDISABLE',$user);
945  if ($result < 0) { $error++; }
946  // End call triggers
947  }
948 
949  if ($error)
950  {
951  $this->db->rollback();
952  return -$error;
953  }
954  else
955  {
956  $this->db->commit();
957  return 1;
958  }
959  }
960 
971  public function setCategories($categories)
972  {
973  // Handle single category
974  if (!is_array($categories)) {
975  $categories = array($categories);
976  }
977 
978  // Get current categories
979  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
980  $c = new Categorie($this->db);
981  $existing = $c->containing($this->id, Categorie::TYPE_USER, 'id');
982 
983  // Diff
984  if (is_array($existing)) {
985  $to_del = array_diff($existing, $categories);
986  $to_add = array_diff($categories, $existing);
987  } else {
988  $to_del = array(); // Nothing to delete
989  $to_add = $categories;
990  }
991 
992  // Process
993  foreach ($to_del as $del) {
994  if ($c->fetch($del) > 0) {
995  $c->del_type($this, 'user');
996  }
997  }
998  foreach ($to_add as $add) {
999  if ($c->fetch($add) > 0) {
1000  $c->add_type($this, 'user');
1001  }
1002  }
1003 
1004  return;
1005  }
1006 
1012  function delete()
1013  {
1014  global $user,$conf,$langs;
1015 
1016  $error=0;
1017 
1018  $this->db->begin();
1019 
1020  $this->fetch($this->id);
1021 
1022  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1023 
1024  // Remove rights
1025  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id;
1026 
1027  if (! $error && ! $this->db->query($sql))
1028  {
1029  $error++;
1030  $this->error = $this->db->lasterror();
1031  }
1032 
1033  // Remove group
1034  $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user WHERE fk_user = ".$this->id;
1035  if (! $error && ! $this->db->query($sql))
1036  {
1037  $error++;
1038  $this->error = $this->db->lasterror();
1039  }
1040 
1041  // If contact, remove link
1042  if ($this->contact_id)
1043  {
1044  $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET fk_user_creat = null WHERE rowid = ".$this->contact_id;
1045  if (! $error && ! $this->db->query($sql))
1046  {
1047  $error++;
1048  $this->error = $this->db->lasterror();
1049  }
1050  }
1051 
1052  // Remove extrafields
1053  if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
1054  {
1055  $result=$this->deleteExtraFields();
1056  if ($result < 0)
1057  {
1058  $error++;
1059  dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1060  }
1061  }
1062 
1063  // Remove user
1064  if (! $error)
1065  {
1066  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->id;
1067  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1068  if (! $this->db->query($sql))
1069  {
1070  $error++;
1071  $this->error = $this->db->lasterror();
1072  }
1073  }
1074 
1075  if (! $error)
1076  {
1077  // Call trigger
1078  $result=$this->call_trigger('USER_DELETE',$user);
1079  if ($result < 0)
1080  {
1081  $error++;
1082  $this->db->rollback();
1083  return -1;
1084  }
1085  // End call triggers
1086 
1087  $this->db->commit();
1088  return 1;
1089  }
1090  else
1091  {
1092  $this->db->rollback();
1093  return -1;
1094  }
1095  }
1096 
1104  function create($user, $notrigger=0)
1105  {
1106  global $conf,$langs;
1107  global $mysoc;
1108 
1109  // Clean parameters
1110  $this->login = trim($this->login);
1111  if (! isset($this->entity)) $this->entity=$conf->entity; // If not defined, we use default value
1112 
1113  dol_syslog(get_class($this)."::create login=".$this->login.", user=".(is_object($user)?$user->id:''), LOG_DEBUG);
1114 
1115  // Check parameters
1116  if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
1117  {
1118  $langs->load("errors");
1119  $this->error = $langs->trans("ErrorBadEMail",$this->email);
1120  return -1;
1121  }
1122  if (empty($this->login))
1123  {
1124  $langs->load("errors");
1125  $this->error = $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Login"));
1126  return -1;
1127  }
1128 
1129  $this->datec = dol_now();
1130 
1131  $error=0;
1132  $this->db->begin();
1133 
1134  $sql = "SELECT login FROM ".MAIN_DB_PREFIX."user";
1135  $sql.= " WHERE login ='".$this->db->escape($this->login)."'";
1136  $sql.= " AND entity IN (0,".$this->db->escape($conf->entity).")";
1137 
1138  dol_syslog(get_class($this)."::create", LOG_DEBUG);
1139  $resql=$this->db->query($sql);
1140  if ($resql)
1141  {
1142  $num = $this->db->num_rows($resql);
1143  $this->db->free($resql);
1144 
1145  if ($num)
1146  {
1147  $this->error = 'ErrorLoginAlreadyExists';
1148  dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
1149  $this->db->rollback();
1150  return -6;
1151  }
1152  else
1153  {
1154  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user (datec,login,ldap_sid,entity)";
1155  $sql.= " VALUES('".$this->db->idate($this->datec)."','".$this->db->escape($this->login)."','".$this->db->escape($this->ldap_sid)."',".$this->db->escape($this->entity).")";
1156  $result=$this->db->query($sql);
1157 
1158  dol_syslog(get_class($this)."::create", LOG_DEBUG);
1159  if ($result)
1160  {
1161  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."user");
1162 
1163  // Set default rights
1164  if ($this->set_default_rights() < 0)
1165  {
1166  $this->error='ErrorFailedToSetDefaultRightOfUser';
1167  $this->db->rollback();
1168  return -5;
1169  }
1170 
1171  // Update minor fields
1172  $result = $this->update($user,1,1);
1173  if ($result < 0)
1174  {
1175  $this->db->rollback();
1176  return -4;
1177  }
1178 
1179  if (! empty($conf->global->STOCK_USERSTOCK_AUTOCREATE))
1180  {
1181  require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1182  $langs->load("stocks");
1183  $entrepot = new Entrepot($this->db);
1184  $entrepot->libelle = $langs->trans("PersonalStock",$this->getFullName($langs));
1185  $entrepot->description = $langs->trans("ThisWarehouseIsPersonalStock",$this->getFullName($langs));
1186  $entrepot->statut = 1;
1187  $entrepot->country_id = $mysoc->country_id;
1188  $entrepot->create($user);
1189  }
1190 
1191  if (! $notrigger)
1192  {
1193  // Call trigger
1194  $result=$this->call_trigger('USER_CREATE',$user);
1195  if ($result < 0) { $error++; }
1196  // End call triggers
1197  }
1198 
1199  if (! $error)
1200  {
1201  $this->db->commit();
1202  return $this->id;
1203  }
1204  else
1205  {
1206  //$this->error=$interface->error;
1207  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
1208  $this->db->rollback();
1209  return -3;
1210  }
1211  }
1212  else
1213  {
1214  $this->error=$this->db->lasterror();
1215  $this->db->rollback();
1216  return -2;
1217  }
1218  }
1219  }
1220  else
1221  {
1222  $this->error=$this->db->lasterror();
1223  $this->db->rollback();
1224  return -1;
1225  }
1226  }
1227 
1228 
1229  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1238  function create_from_contact($contact,$login='',$password='')
1239  {
1240  // phpcs:enable
1241  global $conf,$user,$langs;
1242 
1243  $error=0;
1244 
1245  // Define parameters
1246  $this->admin = 0;
1247  $this->lastname = $contact->lastname;
1248  $this->firstname = $contact->firstname;
1249  $this->gender = $contact->gender;
1250  $this->email = $contact->email;
1251  $this->skype = $contact->skype;
1252  $this->twitter = $contact->twitter;
1253  $this->facebook = $contact->facebook;
1254  $this->office_phone = $contact->phone_pro;
1255  $this->office_fax = $contact->fax;
1256  $this->user_mobile = $contact->phone_mobile;
1257  $this->address = $contact->address;
1258  $this->zip = $contact->zip;
1259  $this->town = $contact->town;
1260  $this->state_id = $contact->state_id;
1261  $this->country_id = $contact->country_id;
1262  $this->employee = 0;
1263 
1264  if (empty($login)) $login=strtolower(substr($contact->firstname, 0, 4)) . strtolower(substr($contact->lastname, 0, 4));
1265  $this->login = $login;
1266 
1267  $this->db->begin();
1268 
1269  // Cree et positionne $this->id
1270  $result=$this->create($user);
1271  if ($result > 0)
1272  {
1273  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1274  $sql.= " SET fk_socpeople=".$contact->id;
1275  if ($contact->socid) $sql.=", fk_soc=".$contact->socid;
1276  $sql.= " WHERE rowid=".$this->id;
1277  $resql=$this->db->query($sql);
1278 
1279  dol_syslog(get_class($this)."::create_from_contact", LOG_DEBUG);
1280  if ($resql)
1281  {
1282  $this->context['createfromcontact']='createfromcontact';
1283 
1284  // Call trigger
1285  $result=$this->call_trigger('USER_CREATE',$user);
1286  if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1287  // End call triggers
1288 
1289  $this->db->commit();
1290  return $this->id;
1291  }
1292  else
1293  {
1294  $this->error=$this->db->error();
1295 
1296  $this->db->rollback();
1297  return -1;
1298  }
1299  }
1300  else
1301  {
1302  // $this->error deja positionne
1303  dol_syslog(get_class($this)."::create_from_contact - 0");
1304 
1305  $this->db->rollback();
1306  return $result;
1307  }
1308  }
1309 
1310  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1318  function create_from_member($member,$login='')
1319  {
1320  // phpcs:enable
1321  global $conf,$user,$langs;
1322 
1323  // Positionne parametres
1324  $this->admin = 0;
1325  $this->lastname = $member->lastname;
1326  $this->firstname = $member->firstname;
1327  $this->gender = $member->gender;
1328  $this->email = $member->email;
1329  $this->fk_member = $member->id;
1330  $this->pass = $member->pass;
1331  $this->address = $member->address;
1332  $this->zip = $member->zip;
1333  $this->town = $member->town;
1334  $this->state_id = $member->state_id;
1335  $this->country_id = $member->country_id;
1336 
1337  if (empty($login)) $login=strtolower(substr($member->firstname, 0, 4)) . strtolower(substr($member->lastname, 0, 4));
1338  $this->login = $login;
1339 
1340  $this->db->begin();
1341 
1342  // Create and set $this->id
1343  $result=$this->create($user);
1344  if ($result > 0)
1345  {
1346  $newpass=$this->setPassword($user,$this->pass);
1347  if (is_numeric($newpass) && $newpass < 0) $result=-2;
1348 
1349  if ($result > 0 && $member->fk_soc) // If member is linked to a thirdparty
1350  {
1351  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1352  $sql.= " SET fk_soc=".$member->fk_soc;
1353  $sql.= " WHERE rowid=".$this->id;
1354 
1355  dol_syslog(get_class($this)."::create_from_member", LOG_DEBUG);
1356  $resql=$this->db->query($sql);
1357  if ($resql)
1358  {
1359  $this->db->commit();
1360  return $this->id;
1361  }
1362  else
1363  {
1364  $this->error=$this->db->lasterror();
1365 
1366  $this->db->rollback();
1367  return -1;
1368  }
1369  }
1370  }
1371 
1372  if ($result > 0)
1373  {
1374  $this->db->commit();
1375  return $this->id;
1376  }
1377  else
1378  {
1379  // $this->error deja positionne
1380  $this->db->rollback();
1381  return -2;
1382  }
1383  }
1384 
1385  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1392  {
1393  // phpcs:enable
1394  global $conf;
1395 
1396  $sql = "SELECT id FROM ".MAIN_DB_PREFIX."rights_def";
1397  $sql.= " WHERE bydefault = 1";
1398  $sql.= " AND entity = ".$conf->entity;
1399 
1400  $resql=$this->db->query($sql);
1401  if ($resql)
1402  {
1403  $num = $this->db->num_rows($resql);
1404  $i = 0;
1405  $rd = array();
1406  while ($i < $num)
1407  {
1408  $row = $this->db->fetch_row($resql);
1409  $rd[$i] = $row[0];
1410  $i++;
1411  }
1412  $this->db->free($resql);
1413  }
1414  $i = 0;
1415  while ($i < $num)
1416  {
1417 
1418  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = $this->id AND fk_id=$rd[$i]";
1419  $result=$this->db->query($sql);
1420 
1421  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (fk_user, fk_id) VALUES ($this->id, $rd[$i])";
1422  $result=$this->db->query($sql);
1423  if (! $result) return -1;
1424  $i++;
1425  }
1426 
1427  return $i;
1428  }
1429 
1440  function update($user, $notrigger=0, $nosyncmember=0, $nosyncmemberpass=0, $nosynccontact=0)
1441  {
1442  global $conf, $langs;
1443 
1444  $nbrowsaffected=0;
1445  $error=0;
1446 
1447  dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncmember=".$nosyncmember.", nosyncmemberpass=".$nosyncmemberpass);
1448 
1449  // Clean parameters
1450  $this->lastname = trim($this->lastname);
1451  $this->firstname = trim($this->firstname);
1452  $this->employee = $this->employee?$this->employee:0;
1453  $this->login = trim($this->login);
1454  $this->gender = trim($this->gender);
1455  $this->birth = trim($this->birth);
1456  $this->pass = trim($this->pass);
1457  $this->api_key = trim($this->api_key);
1458  $this->address = $this->address?trim($this->address):trim($this->address);
1459  $this->zip = $this->zip?trim($this->zip):trim($this->zip);
1460  $this->town = $this->town?trim($this->town):trim($this->town);
1461  $this->state_id = trim($this->state_id);
1462  $this->country_id = ($this->country_id > 0)?$this->country_id:0;
1463  $this->office_phone = trim($this->office_phone);
1464  $this->office_fax = trim($this->office_fax);
1465  $this->user_mobile = trim($this->user_mobile);
1466  $this->email = trim($this->email);
1467 
1468  $this->skype = trim($this->skype);
1469  $this->twitter = trim($this->twitter);
1470  $this->facebook = trim($this->facebook);
1471 
1472  $this->job = trim($this->job);
1473  $this->signature = trim($this->signature);
1474  $this->note = trim($this->note);
1475  $this->openid = trim(empty($this->openid)?'':$this->openid); // Avoid warning
1476  $this->admin = $this->admin?$this->admin:0;
1477  $this->address = empty($this->address)?'':$this->address;
1478  $this->zip = empty($this->zip)?'':$this->zip;
1479  $this->town = empty($this->town)?'':$this->town;
1480  $this->accountancy_code = trim($this->accountancy_code);
1481  $this->color = empty($this->color)?'':$this->color;
1482  $this->dateemployment = empty($this->dateemployment)?'':$this->dateemployment;
1483  $this->dateemploymentend = empty($this->dateemploymentend)?'':$this->dateemploymentend;
1484 
1485  // Check parameters
1486  if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
1487  {
1488  $langs->load("errors");
1489  $this->error = $langs->trans("ErrorBadEMail",$this->email);
1490  return -1;
1491  }
1492  if (empty($this->login))
1493  {
1494  $langs->load("errors");
1495  $this->error = $langs->trans("ErrorFieldRequired",$this->login);
1496  return -1;
1497  }
1498 
1499  $this->db->begin();
1500 
1501  // Update datas
1502  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
1503  $sql.= " lastname = '".$this->db->escape($this->lastname)."'";
1504  $sql.= ", firstname = '".$this->db->escape($this->firstname)."'";
1505  $sql.= ", employee = ".(int) $this->employee;
1506  $sql.= ", login = '".$this->db->escape($this->login)."'";
1507  $sql.= ", api_key = ".($this->api_key ? "'".$this->db->escape($this->api_key)."'" : "null");
1508  $sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
1509  $sql.= ", birth=".(strval($this->birth)!='' ? "'".$this->db->idate($this->birth)."'" : 'null');
1510  if (! empty($user->admin)) $sql.= ", admin = ".(int) $this->admin; // admin flag can be set/unset only by an admin user
1511  $sql.= ", address = '".$this->db->escape($this->address)."'";
1512  $sql.= ", zip = '".$this->db->escape($this->zip)."'";
1513  $sql.= ", town = '".$this->db->escape($this->town)."'";
1514  $sql.= ", fk_state = ".((! empty($this->state_id) && $this->state_id > 0)?"'".$this->db->escape($this->state_id)."'":"null");
1515  $sql.= ", fk_country = ".((! empty($this->country_id) && $this->country_id > 0)?"'".$this->db->escape($this->country_id)."'":"null");
1516  $sql.= ", office_phone = '".$this->db->escape($this->office_phone)."'";
1517  $sql.= ", office_fax = '".$this->db->escape($this->office_fax)."'";
1518  $sql.= ", user_mobile = '".$this->db->escape($this->user_mobile)."'";
1519  $sql.= ", email = '".$this->db->escape($this->email)."'";
1520  $sql.= ", skype = '".$this->db->escape($this->skype)."'";
1521  $sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
1522  $sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
1523  $sql.= ", job = '".$this->db->escape($this->job)."'";
1524  $sql.= ", signature = '".$this->db->escape($this->signature)."'";
1525  $sql.= ", accountancy_code = '".$this->db->escape($this->accountancy_code)."'";
1526  $sql.= ", color = '".$this->db->escape($this->color)."'";
1527  $sql.= ", dateemployment=".(strval($this->dateemployment)!='' ? "'".$this->db->idate($this->dateemployment)."'" : 'null');
1528  $sql.= ", dateemploymentend=".(strval($this->dateemploymentend)!='' ? "'".$this->db->idate($this->dateemploymentend)."'" : 'null');
1529  $sql.= ", note = '".$this->db->escape($this->note)."'";
1530  $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null");
1531  $sql.= ", openid = ".($this->openid?"'".$this->db->escape($this->openid)."'":"null");
1532  $sql.= ", fk_user = ".($this->fk_user > 0?"'".$this->db->escape($this->fk_user)."'":"null");
1533  if (isset($this->thm) || $this->thm != '') $sql.= ", thm= ".($this->thm != ''?"'".$this->db->escape($this->thm)."'":"null");
1534  if (isset($this->tjm) || $this->tjm != '') $sql.= ", tjm= ".($this->tjm != ''?"'".$this->db->escape($this->tjm)."'":"null");
1535  if (isset($this->salary) || $this->salary != '') $sql.= ", salary= ".($this->salary != ''?"'".$this->db->escape($this->salary)."'":"null");
1536  if (isset($this->salaryextra) || $this->salaryextra != '') $sql.= ", salaryextra= ".($this->salaryextra != ''?"'".$this->db->escape($this->salaryextra)."'":"null");
1537  $sql.= ", weeklyhours= ".($this->weeklyhours != ''?"'".$this->db->escape($this->weeklyhours)."'":"null");
1538  $sql.= ", entity = '".$this->db->escape($this->entity)."'";
1539  $sql.= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null');
1540  $sql.= ", default_c_exp_tax_cat = ".($this->default_c_exp_tax_cat > 0 ? $this->default_c_exp_tax_cat : 'null');
1541 
1542  $sql.= " WHERE rowid = ".$this->id;
1543 
1544  dol_syslog(get_class($this)."::update", LOG_DEBUG);
1545  $resql = $this->db->query($sql);
1546  if ($resql)
1547  {
1548  $nbrowsaffected+=$this->db->affected_rows($resql);
1549 
1550  // Update password
1551  if (!empty($this->pass))
1552  {
1553  if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted)
1554  {
1555  // Si mot de passe saisi et different de celui en base
1556  $result=$this->setPassword($user,$this->pass,0,$notrigger,$nosyncmemberpass);
1557  if (! $nbrowsaffected) $nbrowsaffected++;
1558  }
1559  }
1560 
1561  // If user is linked to a member, remove old link to this member
1562  if ($this->fk_member > 0)
1563  {
1564  dol_syslog(get_class($this)."::update remove link with member. We will recreate it later", LOG_DEBUG);
1565  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member;
1566  $resql = $this->db->query($sql);
1567  if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
1568  }
1569  // Set link to user
1570  dol_syslog(get_class($this)."::update set link with member", LOG_DEBUG);
1571  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member =".($this->fk_member>0?$this->fk_member:'null')." where rowid = ".$this->id;
1572  $resql = $this->db->query($sql);
1573  if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
1574 
1575  if ($nbrowsaffected) // If something has changed in data
1576  {
1577  if ($this->fk_member > 0 && ! $nosyncmember)
1578  {
1579  dol_syslog(get_class($this)."::update user is linked with a member. We try to update member too.", LOG_DEBUG);
1580 
1581  require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1582 
1583  // This user is linked with a member, so we also update member information
1584  // if this is an update.
1585  $adh=new Adherent($this->db);
1586  $result=$adh->fetch($this->fk_member);
1587 
1588  if ($result >= 0)
1589  {
1590  $adh->firstname=$this->firstname;
1591  $adh->lastname=$this->lastname;
1592  $adh->login=$this->login;
1593  $adh->gender=$this->gender;
1594  $adh->birth=$this->birth;
1595 
1596  $adh->pass=$this->pass;
1597 
1598  $adh->societe=(empty($adh->societe) && $this->societe_id ? $this->societe_id : $adh->societe);
1599 
1600  $adh->address=$this->address;
1601  $adh->town=$this->town;
1602  $adh->zip=$this->zip;
1603  $adh->state_id=$this->state_id;
1604  $adh->country_id=$this->country_id;
1605 
1606  $adh->email=$this->email;
1607 
1608  $adh->skype=$this->skype;
1609  $adh->twitter=$this->twitter;
1610  $adh->facebook=$this->facebook;
1611 
1612  $adh->phone=$this->office_phone;
1613  $adh->phone_mobile=$this->user_mobile;
1614 
1615  $adh->user_id=$this->id;
1616  $adh->user_login=$this->login;
1617 
1618  $result=$adh->update($user,0,1,0);
1619  if ($result < 0)
1620  {
1621  $this->error=$adh->error;
1622  $this->errors=$adh->errors;
1623  dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR);
1624  $error++;
1625  }
1626  }
1627  else
1628  {
1629  $this->error=$adh->error;
1630  $this->errors=$adh->errors;
1631  $error++;
1632  }
1633  }
1634 
1635  if ($this->contact_id > 0 && ! $nosynccontact)
1636  {
1637  dol_syslog(get_class($this)."::update user is linked with a contact. We try to update contact too.", LOG_DEBUG);
1638 
1639  require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
1640 
1641  // This user is linked with a contact, so we also update contact information
1642  // if this is an update.
1643  $tmpobj=new Contact($this->db);
1644  $result=$tmpobj->fetch($this->contact_id);
1645 
1646  if ($result >= 0)
1647  {
1648  $tmpobj->firstname=$this->firstname;
1649  $tmpobj->lastname=$this->lastname;
1650  $tmpobj->login=$this->login;
1651  $tmpobj->gender=$this->gender;
1652  $tmpobj->birth=$this->birth;
1653 
1654  //$tmpobj->pass=$this->pass;
1655 
1656  //$tmpobj->societe=(empty($tmpobj->societe) && $this->societe_id ? $this->societe_id : $tmpobj->societe);
1657 
1658  $tmpobj->email=$this->email;
1659 
1660  $tmpobj->skype=$this->skype;
1661  $tmpobj->twitter=$this->twitter;
1662  $tmpobj->facebook=$this->facebook;
1663 
1664  $tmpobj->phone_pro=$this->office_phone;
1665  $tmpobj->phone_mobile=$this->user_mobile;
1666  $tmpobj->fax=$this->office_fax;
1667 
1668  $tmpobj->address=$this->address;
1669  $tmpobj->town=$this->town;
1670  $tmpobj->zip=$this->zip;
1671  $tmpobj->state_id=$this->state_id;
1672  $tmpobj->country_id=$this->country_id;
1673 
1674  $tmpobj->user_id=$this->id;
1675  $tmpobj->user_login=$this->login;
1676 
1677  $result=$tmpobj->update($tmpobj->id, $user, 0, 'update', 1);
1678  if ($result < 0)
1679  {
1680  $this->error=$tmpobj->error;
1681  $this->errors=$tmpobj->errors;
1682  dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR);
1683  $error++;
1684  }
1685  }
1686  else
1687  {
1688  $this->error=$tmpobj->error;
1689  $this->errors=$tmpobj->errors;
1690  $error++;
1691  }
1692  }
1693  }
1694 
1695  $action='update';
1696 
1697  // Actions on extra fields
1698  if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))
1699  {
1700  $result=$this->insertExtraFields();
1701  if ($result < 0)
1702  {
1703  $error++;
1704  }
1705  }
1706 
1707  if (! $error && ! $notrigger)
1708  {
1709  // Call trigger
1710  $result=$this->call_trigger('USER_MODIFY',$user);
1711  if ($result < 0) { $error++; }
1712  // End call triggers
1713  }
1714 
1715  if (! $error)
1716  {
1717  $this->db->commit();
1718  return $nbrowsaffected;
1719  }
1720  else
1721  {
1722  dol_syslog(get_class($this)."::update error=".$this->error,LOG_ERR);
1723  $this->db->rollback();
1724  return -1;
1725  }
1726  }
1727  else
1728  {
1729  $this->error=$this->db->lasterror();
1730  $this->db->rollback();
1731  return -2;
1732  }
1733  }
1734 
1735  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1743  {
1744  // phpcs:enable
1745  $now=dol_now();
1746 
1747  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
1748  $sql.= " datepreviouslogin = datelastlogin,";
1749  $sql.= " datelastlogin = '".$this->db->idate($now)."',";
1750  $sql.= " tms = tms"; // La date de derniere modif doit changer sauf pour la mise a jour de date de derniere connexion
1751  $sql.= " WHERE rowid = ".$this->id;
1752 
1753  dol_syslog(get_class($this)."::update_last_login_date user->id=".$this->id." ".$sql, LOG_DEBUG);
1754  $resql = $this->db->query($sql);
1755  if ($resql)
1756  {
1757  $this->datepreviouslogin=$this->datelastlogin;
1758  $this->datelastlogin=$now;
1759  return 1;
1760  }
1761  else
1762  {
1763  $this->error=$this->db->lasterror().' sql='.$sql;
1764  return -1;
1765  }
1766  }
1767 
1768 
1779  function setPassword($user, $password='', $changelater=0, $notrigger=0, $nosyncmember=0)
1780  {
1781  global $conf, $langs;
1782  require_once DOL_DOCUMENT_ROOT .'/core/lib/security2.lib.php';
1783 
1784  $error=0;
1785 
1786  dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." changelater=".$changelater." notrigger=".$notrigger." nosyncmember=".$nosyncmember, LOG_DEBUG);
1787 
1788  // If new password not provided, we generate one
1789  if (! $password)
1790  {
1791  $password=getRandomPassword(false);
1792  }
1793 
1794  // Crypt password
1795  $password_crypted = dol_hash($password);
1796 
1797  // Mise a jour
1798  if (! $changelater)
1799  {
1800  if (! is_object($this->oldcopy)) $this->oldcopy = clone $this;
1801 
1802  $this->db->begin();
1803 
1804  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1805  $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."',";
1806  $sql.= " pass_temp = null";
1807  if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
1808  {
1809  $sql.= ", pass = null";
1810  }
1811  else
1812  {
1813  $sql.= ", pass = '".$this->db->escape($password)."'";
1814  }
1815  $sql.= " WHERE rowid = ".$this->id;
1816 
1817  dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1818  $result = $this->db->query($sql);
1819  if ($result)
1820  {
1821  if ($this->db->affected_rows($result))
1822  {
1823  $this->pass=$password;
1824  $this->pass_indatabase=$password;
1825  $this->pass_indatabase_crypted=$password_crypted;
1826 
1827  if ($this->fk_member && ! $nosyncmember)
1828  {
1829  require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1830 
1831  // This user is linked with a member, so we also update members informations
1832  // if this is an update.
1833  $adh=new Adherent($this->db);
1834  $result=$adh->fetch($this->fk_member);
1835 
1836  if ($result >= 0)
1837  {
1838  $result=$adh->setPassword($user,$this->pass,(empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1),1); // Cryptage non gere dans module adherent
1839  if ($result < 0)
1840  {
1841  $this->error=$adh->error;
1842  dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR);
1843  $error++;
1844  }
1845  }
1846  else
1847  {
1848  $this->error=$adh->error;
1849  $error++;
1850  }
1851  }
1852 
1853  dol_syslog(get_class($this)."::setPassword notrigger=".$notrigger." error=".$error,LOG_DEBUG);
1854 
1855  if (! $error && ! $notrigger)
1856  {
1857  // Call trigger
1858  $result=$this->call_trigger('USER_NEW_PASSWORD',$user);
1859  if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1860  // End call triggers
1861  }
1862 
1863  $this->db->commit();
1864  return $this->pass;
1865  }
1866  else
1867  {
1868  $this->db->rollback();
1869  return 0;
1870  }
1871  }
1872  else
1873  {
1874  $this->db->rollback();
1875  dol_print_error($this->db);
1876  return -1;
1877  }
1878  }
1879  else
1880  {
1881  // We store clear password in password temporary field.
1882  // After receiving confirmation link, we will crypt it and store it in pass_crypted
1883  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
1884  $sql.= " SET pass_temp = '".$this->db->escape($password)."'";
1885  $sql.= " WHERE rowid = ".$this->id;
1886 
1887  dol_syslog(get_class($this)."::setPassword", LOG_DEBUG); // No log
1888  $result = $this->db->query($sql);
1889  if ($result)
1890  {
1891  return $password;
1892  }
1893  else
1894  {
1895  dol_print_error($this->db);
1896  return -3;
1897  }
1898  }
1899  }
1900 
1901 
1902  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1911  function send_password($user, $password='', $changelater=0)
1912  {
1913  // phpcs:enable
1914  global $conf, $langs;
1915  global $dolibarr_main_url_root;
1916 
1917  require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
1918 
1919  $msgishtml=0;
1920 
1921  // Define $msg
1922  $mesg = '';
1923 
1924  $outputlangs=new Translate("",$conf);
1925  if (isset($this->conf->MAIN_LANG_DEFAULT)
1926  && $this->conf->MAIN_LANG_DEFAULT != 'auto')
1927  { // If user has defined its own language (rare because in most cases, auto is used)
1928  $outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT);
1929  }
1930  else
1931  { // If user has not defined its own language, we used current language
1932  $outputlangs=$langs;
1933  }
1934 
1935  // Load translation files required by the page
1936  $outputlangs->loadLangs(array("main", "errors", "users", "other"));
1937 
1938  $appli=constant('DOL_APPLICATION_TITLE');
1939  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
1940 
1941  $subject = $outputlangs->transnoentitiesnoconv("SubjectNewPassword", $appli);
1942 
1943  // Define $urlwithroot
1944  $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
1945  $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
1946 
1947  if (! $changelater)
1948  {
1949  $url = $urlwithroot.'/';
1950 
1951  $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived").".\n";
1952  $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyIs")." :\n\n";
1953  $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n";
1954  $mesg.= $outputlangs->transnoentitiesnoconv("Password")." = ".$password."\n\n";
1955  $mesg.= "\n";
1956 
1957  $mesg.= $outputlangs->transnoentitiesnoconv("ClickHereToGoTo", $appli).': '.$url."\n\n";
1958  $mesg.= "--\n";
1959  $mesg.= $user->getFullName($outputlangs); // Username that make then sending
1960 
1961  dol_syslog(get_class($this)."::send_password changelater is off, url=".$url);
1962  }
1963  else
1964  {
1965  $url = $urlwithroot.'/user/passwordforgotten.php?action=validatenewpassword&username='.$this->login."&passwordhash=".dol_hash($password);
1966 
1967  $mesg.= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived")."\n";
1968  $mesg.= $outputlangs->transnoentitiesnoconv("NewKeyWillBe")." :\n\n";
1969  $mesg.= $outputlangs->transnoentitiesnoconv("Login")." = ".$this->login."\n";
1970  $mesg.= $outputlangs->transnoentitiesnoconv("Password")." = ".$password."\n\n";
1971  $mesg.= "\n";
1972  $mesg.= $outputlangs->transnoentitiesnoconv("YouMustClickToChange")." :\n";
1973  $mesg.= $url."\n\n";
1974  $mesg.= $outputlangs->transnoentitiesnoconv("ForgetIfNothing")."\n\n";
1975 
1976  dol_syslog(get_class($this)."::send_password changelater is on, url=".$url);
1977  }
1978 
1979  $mailfile = new CMailFile(
1980  $subject,
1981  $this->email,
1982  $conf->global->MAIN_MAIL_EMAIL_FROM,
1983  $mesg,
1984  array(),
1985  array(),
1986  array(),
1987  '',
1988  '',
1989  0,
1990  $msgishtml
1991  );
1992 
1993  if ($mailfile->sendfile())
1994  {
1995  return 1;
1996  }
1997  else
1998  {
1999  $langs->trans("errors");
2000  $this->error=$langs->trans("ErrorFailedToSendPassword").' '.$mailfile->error;
2001  return -1;
2002  }
2003  }
2004 
2010  function error()
2011  {
2012  return $this->error;
2013  }
2014 
2015 
2016  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2023  {
2024  // phpcs:enable
2025  $sql = "SELECT url, login, pass, poste ";
2026  $sql.= " FROM ".MAIN_DB_PREFIX."user_clicktodial as u";
2027  $sql.= " WHERE u.fk_user = ".$this->id;
2028 
2029  $resql = $this->db->query($sql);
2030  if ($resql)
2031  {
2032  if ($this->db->num_rows($resql))
2033  {
2034  $obj = $this->db->fetch_object($resql);
2035 
2036  $this->clicktodial_url = $obj->url;
2037  $this->clicktodial_login = $obj->login;
2038  $this->clicktodial_password = $obj->pass;
2039  $this->clicktodial_poste = $obj->poste;
2040  }
2041 
2042  $this->clicktodial_loaded = 1; // Data loaded (found or not)
2043 
2044  $this->db->free($resql);
2045  return 1;
2046  }
2047  else
2048  {
2049  $this->error=$this->db->error();
2050  return -1;
2051  }
2052  }
2053 
2054  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2061  {
2062  // phpcs:enable
2063  $this->db->begin();
2064 
2065  $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_clicktodial";
2066  $sql .= " WHERE fk_user = ".$this->id;
2067 
2068  dol_syslog(get_class($this).'::update_clicktodial', LOG_DEBUG);
2069  $result = $this->db->query($sql);
2070 
2071  $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_clicktodial";
2072  $sql .= " (fk_user,url,login,pass,poste)";
2073  $sql .= " VALUES (".$this->id;
2074  $sql .= ", '". $this->db->escape($this->clicktodial_url) ."'";
2075  $sql .= ", '". $this->db->escape($this->clicktodial_login) ."'";
2076  $sql .= ", '". $this->db->escape($this->clicktodial_password) ."'";
2077  $sql .= ", '". $this->db->escape($this->clicktodial_poste) ."')";
2078 
2079  dol_syslog(get_class($this).'::update_clicktodial', LOG_DEBUG);
2080  $result = $this->db->query($sql);
2081  if ($result)
2082  {
2083  $this->db->commit();
2084  return 1;
2085  }
2086  else
2087  {
2088  $this->db->rollback();
2089  $this->error=$this->db->lasterror();
2090  return -1;
2091  }
2092  }
2093 
2094 
2095  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2104  function SetInGroup($group, $entity, $notrigger=0)
2105  {
2106  // phpcs:enable
2107  global $conf, $langs, $user;
2108 
2109  $error=0;
2110 
2111  $this->db->begin();
2112 
2113  $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user";
2114  $sql.= " WHERE fk_user = ".$this->id;
2115  $sql.= " AND fk_usergroup = ".$group;
2116  $sql.= " AND entity = ".$entity;
2117 
2118  $result = $this->db->query($sql);
2119 
2120  $sql = "INSERT INTO ".MAIN_DB_PREFIX."usergroup_user (entity, fk_user, fk_usergroup)";
2121  $sql.= " VALUES (".$entity.",".$this->id.",".$group.")";
2122 
2123  $result = $this->db->query($sql);
2124  if ($result)
2125  {
2126  if (! $error && ! $notrigger)
2127  {
2128  $this->newgroupid=$group; // deprecated. Remove this.
2129  $this->context = array('audit'=>$langs->trans("UserSetInGroup"), 'newgroupid'=>$group);
2130 
2131  // Call trigger
2132  $result=$this->call_trigger('USER_MODIFY',$user);
2133  if ($result < 0) { $error++; }
2134  // End call triggers
2135  }
2136 
2137  if (! $error)
2138  {
2139  $this->db->commit();
2140  return 1;
2141  }
2142  else
2143  {
2144  dol_syslog(get_class($this)."::SetInGroup ".$this->error, LOG_ERR);
2145  $this->db->rollback();
2146  return -2;
2147  }
2148  }
2149  else
2150  {
2151  $this->error=$this->db->lasterror();
2152  $this->db->rollback();
2153  return -1;
2154  }
2155  }
2156 
2157  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2166  function RemoveFromGroup($group, $entity, $notrigger=0)
2167  {
2168  // phpcs:enable
2169  global $conf,$langs,$user;
2170 
2171  $error=0;
2172 
2173  $this->db->begin();
2174 
2175  $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user";
2176  $sql.= " WHERE fk_user = ".$this->id;
2177  $sql.= " AND fk_usergroup = ".$group;
2178  $sql.= " AND entity = ".$entity;
2179 
2180  $result = $this->db->query($sql);
2181  if ($result)
2182  {
2183  if (! $error && ! $notrigger)
2184  {
2185  $this->oldgroupid=$group; // deprecated. Remove this.
2186  $this->context = array('audit'=>$langs->trans("UserRemovedFromGroup"), 'oldgroupid'=>$group);
2187 
2188  // Call trigger
2189  $result=$this->call_trigger('USER_MODIFY',$user);
2190  if ($result < 0) { $error++; }
2191  // End call triggers
2192  }
2193 
2194  if (! $error)
2195  {
2196  $this->db->commit();
2197  return 1;
2198  }
2199  else
2200  {
2201  $this->error=$interface->error;
2202  dol_syslog(get_class($this)."::RemoveFromGroup ".$this->error, LOG_ERR);
2203  $this->db->rollback();
2204  return -2;
2205  }
2206  }
2207  else
2208  {
2209  $this->error=$this->db->lasterror();
2210  $this->db->rollback();
2211  return -1;
2212  }
2213  }
2214 
2215 
2226  function getPhotoUrl($width, $height, $cssclass='', $imagesize='')
2227  {
2228  $result ='<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
2229  $result.=Form::showphoto('userphoto', $this, $width, $height, 0, $cssclass, $imagesize);
2230  $result.='</a>';
2231 
2232  return $result;
2233  }
2234 
2250  function getNomUrl($withpictoimg=0, $option='', $infologin=0, $notooltip=0, $maxlen=24, $hidethirdpartylogo=0, $mode='',$morecss='', $save_lastsearch_value=-1)
2251  {
2252  global $langs, $conf, $db, $hookmanager, $user;
2253  global $dolibarr_main_authentication, $dolibarr_main_demo;
2254  global $menumanager;
2255 
2256  if(!$user->rights->user->user->lire && $user->id !=$this->id) $option='nolink';
2257 
2258  if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
2259 
2260  $result=''; $label='';
2261  $link=''; $linkstart=''; $linkend='';
2262 
2263  if (! empty($this->photo))
2264  {
2265  $label.= '<div class="photointooltip">';
2266  $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
2267  $label.= '</div><div style="clear: both;"></div>';
2268  }
2269 
2270  // Info Login
2271  $label.= '<div class="centpercent">';
2272  $label.= '<u>' . $langs->trans("User") . '</u><br>';
2273  $label.= '<b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs,'');
2274  if (! empty($this->login))
2275  $label.= '<br><b>' . $langs->trans('Login') . ':</b> ' . $this->login;
2276  $label.= '<br><b>' . $langs->trans("EMail").':</b> '.$this->email;
2277  if (! empty($this->admin))
2278  $label.= '<br><b>' . $langs->trans("Administrator").'</b>: '.yn($this->admin);
2279  if (! empty($this->socid) ) // Add thirdparty for external users
2280  {
2281  $thirdpartystatic = new Societe($db);
2282  $thirdpartystatic->fetch($this->socid);
2283  if (empty($hidethirdpartylogo)) $companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink')?'nolink':'')); // picto only of company
2284  $company=' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')';
2285  }
2286  $type=($this->socid?$langs->trans("External").$company:$langs->trans("Internal"));
2287  $label.= '<br><b>' . $langs->trans("Type") . ':</b> ' . $type;
2288  $label.= '<br><b>' . $langs->trans("Status").'</b>: '.$this->getLibStatut(0);
2289  $label.='</div>';
2290  if ($infologin > 0)
2291  {
2292  $label.= '<br>';
2293  $label.= '<br><u>'.$langs->trans("Connection").'</u>';
2294  $label.= '<br><b>'.$langs->trans("IPAddress").'</b>: '.$_SERVER["REMOTE_ADDR"];
2295  if (! empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $label.= '<br><b>'.$langs->trans("ConnectedOnMultiCompany").':</b> '.$conf->entity.' (user entity '.$this->entity.')';
2296  $label.= '<br><b>'.$langs->trans("AuthenticationMode").':</b> '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo)?'':' (demo)');
2297  $label.= '<br><b>'.$langs->trans("ConnectedSince").':</b> '.dol_print_date($this->datelastlogin,"dayhour",'tzuser');
2298  $label.= '<br><b>'.$langs->trans("PreviousConnexion").':</b> '.dol_print_date($this->datepreviouslogin,"dayhour",'tzuser');
2299  $label.= '<br><b>'.$langs->trans("CurrentTheme").':</b> '.$conf->theme;
2300  $label.= '<br><b>'.$langs->trans("CurrentMenuManager").':</b> '.$menumanager->name;
2301  $s=picto_from_langcode($langs->getDefaultLang());
2302  $label.= '<br><b>'.$langs->trans("CurrentUserLanguage").':</b> '.($s?$s.' ':'').$langs->getDefaultLang();
2303  $label.= '<br><b>'.$langs->trans("Browser").':</b> '.$conf->browser->name.($conf->browser->version?' '.$conf->browser->version:'').' ('.$_SERVER['HTTP_USER_AGENT'].')';
2304  $label.= '<br><b>'.$langs->trans("Layout").':</b> '.$conf->browser->layout;
2305  $label.= '<br><b>'.$langs->trans("Screen").':</b> '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight'];
2306  if ($conf->browser->layout == 'phone') $label.= '<br><b>'.$langs->trans("Phone").':</b> '.$langs->trans("Yes");
2307  if (! empty($_SESSION["disablemodules"])) $label.= '<br><b>'.$langs->trans("DisabledModules").':</b> <br>'.join(', ',explode(',',$_SESSION["disablemodules"]));
2308  }
2309  if ($infologin < 0) $label='';
2310 
2311  $url = DOL_URL_ROOT.'/user/card.php?id='.$this->id;
2312  if ($option == 'leave') $url = DOL_URL_ROOT.'/holiday/list.php?id='.$this->id;
2313 
2314  if ($option != 'nolink')
2315  {
2316  // Add param to save lastsearch_values or not
2317  $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
2318  if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
2319  if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
2320  }
2321 
2322  $linkstart='<a href="'.$url.'"';
2323  $linkclose="";
2324  if (empty($notooltip))
2325  {
2326  if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
2327  {
2328  $langs->load("users");
2329  $label=$langs->trans("ShowUser");
2330  $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
2331  }
2332  $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
2333  $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
2334 
2335  /*
2336  $hookmanager->initHooks(array('userdao'));
2337  $parameters=array('id'=>$this->id);
2338  $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
2339  if ($reshook > 0) $linkclose = $hookmanager->resPrint;
2340  */
2341  }
2342 
2343  $linkstart.=$linkclose.'>';
2344  $linkend='</a>';
2345 
2346  //if ($withpictoimg == -1) $result.='<div class="nowrap">';
2347  $result.=(($option == 'nolink')?'':$linkstart);
2348  if ($withpictoimg)
2349  {
2350  $paddafterimage='';
2351  if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"';
2352  // Only picto
2353  if ($withpictoimg > 0) $picto='<!-- picto user --><div class="inline-block nopadding userimg'.($morecss?' '.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>';
2354  // Picto must be a photo
2355  else $picto='<!-- picto photo user --><div class="inline-block nopadding userimg'.($morecss?' '.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>';
2356  $result.=$picto;
2357  }
2358  if ($withpictoimg > -2 && $withpictoimg != 2)
2359  {
2360  if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<div class="inline-block nopadding valignmiddle usertext'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' '.$morecss:'').'">';
2361  if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen);
2362  else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen);
2363  if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</div>';
2364  }
2365  $result.=(($option == 'nolink')?'':$linkend);
2366  //if ($withpictoimg == -1) $result.='</div>';
2367 
2368  $result.=$companylink;
2369 
2370  global $action;
2371  $hookmanager->initHooks(array('userdao'));
2372  $parameters=array('id'=>$this->id, 'getnomurl'=>$result);
2373  $reshook=$hookmanager->executeHooks('getNomUrl',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
2374  if ($reshook > 0) $result = $hookmanager->resPrint;
2375  else $result .= $hookmanager->resPrint;
2376 
2377  return $result;
2378  }
2379 
2387  function getLoginUrl($withpicto=0,$option='')
2388  {
2389  global $langs, $user;
2390 
2391  $result='';
2392 
2393  $linkstart = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
2394  $linkend='</a>';
2395 
2396  //Check user's rights to see an other user
2397  if((!$user->rights->user->user->lire && $this->id !=$user->id)) $option='nolink';
2398 
2399  if ($option == 'xxx')
2400  {
2401  $linkstart = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
2402  $linkend='</a>';
2403  }
2404 
2405  if ($option == 'nolink')
2406  {
2407  $linkstart = '';
2408  $linkend='';
2409  }
2410 
2411  $result.=$linkstart;
2412  if ($withpicto) $result.=img_object($langs->trans("ShowUser"), 'user', 'class="paddingright"');
2413  $result.=$this->login;
2414  $result.=$linkend;
2415  return $result;
2416  }
2417 
2424  function getLibStatut($mode=0)
2425  {
2426  return $this->LibStatut($this->statut,$mode);
2427  }
2428 
2429  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2437  function LibStatut($statut,$mode=0)
2438  {
2439  // phpcs:enable
2440  global $langs;
2441  $langs->load('users');
2442 
2443  if ($mode == 0)
2444  {
2445  if ($statut == 1) return $langs->trans('Enabled');
2446  elseif ($statut == 0) return $langs->trans('Disabled');
2447  }
2448  elseif ($mode == 1)
2449  {
2450  if ($statut == 1) return $langs->trans('Enabled');
2451  elseif ($statut == 0) return $langs->trans('Disabled');
2452  }
2453  elseif ($mode == 2)
2454  {
2455  if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
2456  elseif ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
2457  }
2458  elseif ($mode == 3)
2459  {
2460  if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
2461  elseif ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
2462  }
2463  elseif ($mode == 4)
2464  {
2465  if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
2466  elseif ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
2467  }
2468  elseif ($mode == 5)
2469  {
2470  if ($statut == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
2471  elseif ($statut == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
2472  }
2473  }
2474 
2475 
2476  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2486  function _load_ldap_dn($info,$mode=0)
2487  {
2488  // phpcs:enable
2489  global $conf;
2490  $dn='';
2491  if ($mode==0) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS].",".$conf->global->LDAP_USER_DN;
2492  elseif ($mode==1) $dn=$conf->global->LDAP_USER_DN;
2493  elseif ($mode==2) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS];
2494  return $dn;
2495  }
2496 
2497  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2503  function _load_ldap_info()
2504  {
2505  // phpcs:enable
2506  global $conf,$langs;
2507 
2508  $info=array();
2509  $keymodified=false;
2510 
2511  // Object classes
2512  $info["objectclass"]=explode(',',$conf->global->LDAP_USER_OBJECT_CLASS);
2513 
2514  $this->fullname=$this->getFullName($langs);
2515 
2516  // Possible LDAP KEY (constname => varname)
2517  $ldapkey = array(
2518  'LDAP_FIELD_FULLNAME' => 'fullname',
2519  'LDAP_FIELD_NAME' => 'lastname',
2520  'LDAP_FIELD_FIRSTNAME' => 'firstname',
2521  'LDAP_FIELD_LOGIN' => 'login',
2522  'LDAP_FIELD_LOGIN_SAMBA'=> 'login',
2523  'LDAP_FIELD_PHONE' => 'office_phone',
2524  'LDAP_FIELD_MOBILE' => 'user_mobile',
2525  'LDAP_FIELD_FAX' => 'office_fax',
2526  'LDAP_FIELD_MAIL' => 'email',
2527  'LDAP_FIELD_SID' => 'ldap_sid',
2528  'LDAP_FIELD_SKYPE' => 'skype',
2529  'LDAP_FIELD_TWITTER' => 'twitter',
2530  'LDAP_FIELD_FACEBOOK' => 'facebook'
2531  );
2532 
2533  // Champs
2534  foreach ($ldapkey as $constname => $varname)
2535  {
2536  if (! empty($this->$varname) && ! empty($conf->global->$constname))
2537  {
2538  $info[$conf->global->$constname] = $this->$varname;
2539 
2540  // Check if it is the LDAP key and if its value has been changed
2541  if (! empty($conf->global->LDAP_KEY_USERS) && $conf->global->LDAP_KEY_USERS == $conf->global->$constname)
2542  {
2543  if (! empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) $keymodified=true; // For check if LDAP key has been modified
2544  }
2545  }
2546  }
2547  if ($this->address && ! empty($conf->global->LDAP_FIELD_ADDRESS)) $info[$conf->global->LDAP_FIELD_ADDRESS] = $this->address;
2548  if ($this->zip && ! empty($conf->global->LDAP_FIELD_ZIP)) $info[$conf->global->LDAP_FIELD_ZIP] = $this->zip;
2549  if ($this->town && ! empty($conf->global->LDAP_FIELD_TOWN)) $info[$conf->global->LDAP_FIELD_TOWN] = $this->town;
2550  if ($this->note_public && ! empty($conf->global->LDAP_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note_public, 2);
2551  if ($this->socid > 0)
2552  {
2553  $soc = new Societe($this->db);
2554  $soc->fetch($this->socid);
2555 
2556  $info[$conf->global->LDAP_FIELD_COMPANY] = $soc->name;
2557  if ($soc->client == 1) $info["businessCategory"] = "Customers";
2558  if ($soc->client == 2) $info["businessCategory"] = "Prospects";
2559  if ($soc->fournisseur == 1) $info["businessCategory"] = "Suppliers";
2560  }
2561 
2562  // When password is modified
2563  if (! empty($this->pass))
2564  {
2565  if (! empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte
2566  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)
2567  }
2568  // Set LDAP password if possible
2569  elseif ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2570  {
2571  if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
2572  {
2573  // Just for the default MD5 !
2574  if (empty($conf->global->MAIN_SECURITY_HASH_ALGO))
2575  {
2576  if ($this->pass_indatabase_crypted && ! empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) {
2577  $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase_crypted, 5); // Create OpenLDAP MD5 password from Dolibarr MD5 password
2578  }
2579  }
2580  }
2581  // Use $this->pass_indatabase value if exists
2582  elseif (! empty($this->pass_indatabase))
2583  {
2584  if (! empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass_indatabase; // $this->pass_indatabase = mot de passe non crypte
2585  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
2586  }
2587  }
2588 
2589  if ($conf->global->LDAP_SERVER_TYPE == 'egroupware')
2590  {
2591  $info["objectclass"][4] = "phpgwContact"; // compatibilite egroupware
2592 
2593  $info['uidnumber'] = $this->id;
2594 
2595  $info['phpgwTz'] = 0;
2596  $info['phpgwMailType'] = 'INTERNET';
2597  $info['phpgwMailHomeType'] = 'INTERNET';
2598 
2599  $info["phpgwContactTypeId"] = 'n';
2600  $info["phpgwContactCatId"] = 0;
2601  $info["phpgwContactAccess"] = "public";
2602 
2603  if (dol_strlen($this->egroupware_id) == 0)
2604  {
2605  $this->egroupware_id = 1;
2606  }
2607 
2608  $info["phpgwContactOwner"] = $this->egroupware_id;
2609 
2610  if ($this->email) $info["rfc822Mailbox"] = $this->email;
2611  if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile;
2612  }
2613 
2614  return $info;
2615  }
2616 
2617 
2625  function initAsSpecimen()
2626  {
2627  global $user,$langs;
2628 
2629  $now=dol_now();
2630 
2631  // Initialise parametres
2632  $this->id=0;
2633  $this->ref = 'SPECIMEN';
2634  $this->specimen=1;
2635 
2636  $this->lastname='DOLIBARR';
2637  $this->firstname='SPECIMEN';
2638  $this->gender='man';
2639  $this->note='This is a note';
2640  $this->email='email@specimen.com';
2641  $this->skype='skypepseudo';
2642  $this->twitter='twitterpseudo';
2643  $this->facebook='facebookpseudo';
2644  $this->office_phone='0999999999';
2645  $this->office_fax='0999999998';
2646  $this->user_mobile='0999999997';
2647  $this->admin=0;
2648  $this->login='dolibspec';
2649  $this->pass='dolibspec';
2650  //$this->pass_indatabase='dolibspec'; Set after a fetch
2651  //$this->pass_indatabase_crypted='e80ca5a88c892b0aaaf7e154853bccab'; Set after a fetch
2652  $this->datec=$now;
2653  $this->datem=$now;
2654 
2655  $this->datelastlogin=$now;
2656  $this->datepreviouslogin=$now;
2657  $this->statut=1;
2658 
2659  //$this->societe_id = 1; For external users
2660  //$this->contact_id = 1; For external users
2661  $this->entity = 1;
2662  }
2663 
2670  function info($id)
2671  {
2672  $sql = "SELECT u.rowid, u.login as ref, u.datec,";
2673  $sql.= " u.tms as date_modification, u.entity";
2674  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
2675  $sql.= " WHERE u.rowid = ".$id;
2676 
2677  $result=$this->db->query($sql);
2678  if ($result)
2679  {
2680  if ($this->db->num_rows($result))
2681  {
2682  $obj = $this->db->fetch_object($result);
2683 
2684  $this->id = $obj->rowid;
2685 
2686  $this->ref = (! $obj->ref) ? $obj->rowid : $obj->ref;
2687  $this->date_creation = $this->db->jdate($obj->datec);
2688  $this->date_modification = $this->db->jdate($obj->date_modification);
2689  $this->entity = $obj->entity;
2690  }
2691 
2692  $this->db->free($result);
2693  }
2694  else
2695  {
2696  dol_print_error($this->db);
2697  }
2698  }
2699 
2700 
2706  function getNbOfEMailings()
2707  {
2708  $sql = "SELECT count(mc.email) as nb";
2709  $sql.= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
2710  $sql.= " WHERE mc.email = '".$this->db->escape($this->email)."'";
2711  $sql.= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec succes
2712 
2713  $resql=$this->db->query($sql);
2714  if ($resql)
2715  {
2716  $obj = $this->db->fetch_object($resql);
2717  $nb=$obj->nb;
2718 
2719  $this->db->free($resql);
2720  return $nb;
2721  }
2722  else
2723  {
2724  $this->error=$this->db->error();
2725  return -1;
2726  }
2727  }
2728 
2737  function getNbOfUsers($limitTo, $option='', $admin=-1)
2738  {
2739  global $conf;
2740 
2741  $sql = "SELECT count(rowid) as nb";
2742  $sql.= " FROM ".MAIN_DB_PREFIX."user";
2743  if ($option == 'superadmin')
2744  {
2745  $sql.= " WHERE entity = 0";
2746  if ($admin >= 0) $sql.= " AND admin = ".$admin;
2747  }
2748  else
2749  {
2750  $sql.=" WHERE entity IN (".getEntity('user',0).")";
2751  if ($limitTo == 'active') $sql.= " AND statut = 1";
2752  if ($admin >= 0) $sql.= " AND admin = ".$admin;
2753  }
2754 
2755  $resql=$this->db->query($sql);
2756  if ($resql)
2757  {
2758  $obj = $this->db->fetch_object($resql);
2759  $nb=$obj->nb;
2760 
2761  $this->db->free($resql);
2762  return $nb;
2763  }
2764  else
2765  {
2766  $this->error=$this->db->lasterror();
2767  return -1;
2768  }
2769  }
2770 
2771  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2779  function update_ldap2dolibarr(&$ldapuser)
2780  {
2781  // phpcs:enable
2782  // TODO: Voir pourquoi le update met à jour avec toutes les valeurs vide (global $user écrase ?)
2783  global $user, $conf;
2784 
2785  $this->firstname=$ldapuser->{$conf->global->LDAP_FIELD_FIRSTNAME};
2786  $this->lastname=$ldapuser->{$conf->global->LDAP_FIELD_NAME};
2787  $this->login=$ldapuser->{$conf->global->LDAP_FIELD_LOGIN};
2788  $this->pass=$ldapuser->{$conf->global->LDAP_FIELD_PASSWORD};
2789  $this->pass_indatabase_crypted=$ldapuser->{$conf->global->LDAP_FIELD_PASSWORD_CRYPTED};
2790 
2791  $this->office_phone=$ldapuser->{$conf->global->LDAP_FIELD_PHONE};
2792  $this->user_mobile=$ldapuser->{$conf->global->LDAP_FIELD_MOBILE};
2793  $this->office_fax=$ldapuser->{$conf->global->LDAP_FIELD_FAX};
2794  $this->email=$ldapuser->{$conf->global->LDAP_FIELD_MAIL};
2795  $this->skype=$ldapuser->{$conf->global->LDAP_FIELD_SKYPE};
2796  $this->twitter=$ldapuser->{$conf->global->LDAP_FIELD_TWITTER};
2797  $this->facebook=$ldapuser->{$conf->global->LDAP_FIELD_FACEBOOK};
2798  $this->ldap_sid=$ldapuser->{$conf->global->LDAP_FIELD_SID};
2799 
2800  $this->job=$ldapuser->{$conf->global->LDAP_FIELD_TITLE};
2801  $this->note=$ldapuser->{$conf->global->LDAP_FIELD_DESCRIPTION};
2802 
2803  $result = $this->update($user);
2804 
2805  dol_syslog(get_class($this)."::update_ldap2dolibarr result=".$result, LOG_DEBUG);
2806 
2807  return $result;
2808  }
2809 
2810 
2811  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2818  function get_children()
2819  {
2820  // phpcs:enable
2821  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."user";
2822  $sql.= " WHERE fk_user = ".$this->id;
2823 
2824  dol_syslog(get_class($this)."::get_children result=".$result, LOG_DEBUG);
2825  $res = $this->db->query($sql);
2826  if ($res)
2827  {
2828  $users = array ();
2829  while ($rec = $this->db->fetch_array($res))
2830  {
2831  $user = new User($this->db);
2832  $user->fetch($rec['rowid']);
2833  $users[] = $user;
2834  }
2835  return $users;
2836  }
2837  else
2838  {
2839  dol_print_error($this->db);
2840  return -1;
2841  }
2842  }
2843 
2844 
2850  private function loadParentOf()
2851  {
2852  global $conf;
2853 
2854  $this->parentof=array();
2855 
2856  // Load array[child]=parent
2857  $sql = "SELECT fk_user as id_parent, rowid as id_son";
2858  $sql.= " FROM ".MAIN_DB_PREFIX."user";
2859  $sql.= " WHERE fk_user <> 0";
2860  $sql.= " AND entity IN (".getEntity('user').")";
2861 
2862  dol_syslog(get_class($this)."::loadParentOf", LOG_DEBUG);
2863  $resql = $this->db->query($sql);
2864  if ($resql)
2865  {
2866  while ($obj= $this->db->fetch_object($resql))
2867  {
2868  $this->parentof[$obj->id_son]=$obj->id_parent;
2869  }
2870  return 1;
2871  }
2872  else
2873  {
2874  dol_print_error($this->db);
2875  return -1;
2876  }
2877  }
2878 
2879  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2893  function get_full_tree($deleteafterid=0, $filter='')
2894  {
2895  // phpcs:enable
2896  global $conf, $user;
2897  global $hookmanager;
2898 
2899  // Actions hooked (by external module)
2900  $hookmanager->initHooks(array('userdao'));
2901 
2902  $this->users = array();
2903 
2904  // Init this->parentof that is array(id_son=>id_parent, ...)
2905  $this->loadParentOf();
2906 
2907  // Init $this->users array
2908  $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
2909  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
2910  // Add fields from hooks
2911  $parameters=array();
2912  $reshook=$hookmanager->executeHooks('printUserListWhere',$parameters); // Note that $action and $object may have been modified by hook
2913  if ($reshook > 0) {
2914  $sql.=$hookmanager->resPrint;
2915  } else {
2916  $sql.= " WHERE u.entity IN (".getEntity('user').")";
2917  }
2918  if ($filter) $sql.=" AND ".$filter;
2919 
2920  dol_syslog(get_class($this)."::get_full_tree get user list", LOG_DEBUG);
2921  $resql = $this->db->query($sql);
2922  if ($resql)
2923  {
2924  $i=0;
2925  while ($obj = $this->db->fetch_object($resql))
2926  {
2927  $this->users[$obj->rowid]['rowid'] = $obj->rowid;
2928  $this->users[$obj->rowid]['id'] = $obj->rowid;
2929  $this->users[$obj->rowid]['fk_user'] = $obj->fk_user;
2930  $this->users[$obj->rowid]['fk_soc'] = $obj->fk_soc;
2931  $this->users[$obj->rowid]['firstname'] = $obj->firstname;
2932  $this->users[$obj->rowid]['lastname'] = $obj->lastname;
2933  $this->users[$obj->rowid]['login'] = $obj->login;
2934  $this->users[$obj->rowid]['statut'] = $obj->statut;
2935  $this->users[$obj->rowid]['entity'] = $obj->entity;
2936  $this->users[$obj->rowid]['email'] = $obj->email;
2937  $this->users[$obj->rowid]['gender'] = $obj->gender;
2938  $this->users[$obj->rowid]['admin'] = $obj->admin;
2939  $this->users[$obj->rowid]['photo'] = $obj->photo;
2940  $i++;
2941  }
2942  }
2943  else
2944  {
2945  dol_print_error($this->db);
2946  return -1;
2947  }
2948 
2949  // We add the fullpath property to each elements of first level (no parent exists)
2950  dol_syslog(get_class($this)."::get_full_tree call to build_path_from_id_user", LOG_DEBUG);
2951  foreach($this->users as $key => $val)
2952  {
2953  $result = $this->build_path_from_id_user($key,0); // Process a branch from the root user key (this user has no parent)
2954  if ($result < 0)
2955  {
2956  $this->error='ErrorLoopInHierarchy';
2957  return -1;
2958  }
2959  }
2960 
2961  // Exclude leaf including $deleteafterid from tree
2962  if ($deleteafterid)
2963  {
2964  //print "Look to discard user ".$deleteafterid."\n";
2965  $keyfilter1='^'.$deleteafterid.'$';
2966  $keyfilter2='_'.$deleteafterid.'$';
2967  $keyfilter3='^'.$deleteafterid.'_';
2968  $keyfilter4='_'.$deleteafterid.'_';
2969  foreach($this->users as $key => $val)
2970  {
2971  if (preg_match('/'.$keyfilter1.'/',$val['fullpath']) || preg_match('/'.$keyfilter2.'/',$val['fullpath'])
2972  || preg_match('/'.$keyfilter3.'/',$val['fullpath']) || preg_match('/'.$keyfilter4.'/',$val['fullpath']))
2973  {
2974  unset($this->users[$key]);
2975  }
2976  }
2977  }
2978 
2979  dol_syslog(get_class($this)."::get_full_tree dol_sort_array", LOG_DEBUG);
2980  $this->users=dol_sort_array($this->users, 'fullname', 'asc', true, false);
2981 
2982  //var_dump($this->users);
2983 
2984  return $this->users;
2985  }
2986 
2995  function getAllChildIds($addcurrentuser=0)
2996  {
2997  $childids=array();
2998 
2999  if (isset($this->cache_childids[$this->id]))
3000  {
3001  $childids = $this->cache_childids[$this->id];
3002  }
3003  else
3004  {
3005  // Init this->users
3006  $this->get_full_tree();
3007 
3008  $idtoscan=$this->id;
3009 
3010  dol_syslog("Build childid for id = ".$idtoscan);
3011  foreach($this->users as $id => $val)
3012  {
3013  //var_dump($val['fullpath']);
3014  if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id'];
3015  }
3016  }
3017  $this->cache_childids[$this->id] = $childids;
3018 
3019  if ($addcurrentuser) $childids[$this->id]=$this->id;
3020 
3021  return $childids;
3022  }
3023 
3024  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3033  function build_path_from_id_user($id_user,$protection=0)
3034  {
3035  // phpcs:enable
3036  dol_syslog(get_class($this)."::build_path_from_id_user id_user=".$id_user." protection=".$protection, LOG_DEBUG);
3037 
3038  if (! empty($this->users[$id_user]['fullpath']))
3039  {
3040  // Already defined
3041  dol_syslog(get_class($this)."::build_path_from_id_user fullpath and fullname already defined", LOG_WARNING);
3042  return 0;
3043  }
3044 
3045  // Define fullpath and fullname
3046  $this->users[$id_user]['fullpath'] = '_'.$id_user;
3047  $this->users[$id_user]['fullname'] = $this->users[$id_user]['lastname'];
3048  $i=0; $cursor_user=$id_user;
3049 
3050  $useridfound=array($id_user);
3051  while (! empty($this->parentof[$cursor_user]))
3052  {
3053  if (in_array($this->parentof[$cursor_user], $useridfound))
3054  {
3055  dol_syslog("The hierarchy of user has a recursive loop", LOG_WARNING);
3056  return -1; // Should not happen. Protection against looping hierarchy
3057  }
3058  $useridfound[]=$this->parentof[$cursor_user];
3059  $this->users[$id_user]['fullpath'] = '_'.$this->parentof[$cursor_user].$this->users[$id_user]['fullpath'];
3060  $this->users[$id_user]['fullname'] = $this->users[$this->parentof[$cursor_user]]['lastname'].' >> '.$this->users[$id_user]['fullname'];
3061  $i++; $cursor_user=$this->parentof[$cursor_user];
3062  }
3063 
3064  // We count number of _ to have level
3065  $this->users[$id_user]['level']=dol_strlen(preg_replace('/[^_]/i','',$this->users[$id_user]['fullpath']));
3066 
3067  return 1;
3068  }
3069 
3078  public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
3079  {
3080  $tables = array(
3081  'user',
3082  );
3083 
3084  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
3085  }
3086 
3087 
3088  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3094  function load_state_board()
3095  {
3096  // phpcs:enable
3097  global $conf;
3098 
3099  $this->nb=array();
3100 
3101  $sql = "SELECT count(u.rowid) as nb";
3102  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
3103  $sql.= " WHERE u.statut > 0";
3104  //$sql.= " AND employee != 0";
3105  $sql.= " AND u.entity IN (".getEntity('user').")";
3106 
3107  $resql=$this->db->query($sql);
3108  if ($resql)
3109  {
3110  while ($obj=$this->db->fetch_object($resql))
3111  {
3112  $this->nb["users"]=$obj->nb;
3113  }
3114  $this->db->free($resql);
3115  return 1;
3116  }
3117  else
3118  {
3119  dol_print_error($this->db);
3120  $this->error=$this->db->error();
3121  return -1;
3122  }
3123  }
3124 
3136  public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
3137  {
3138  global $conf, $user, $langs;
3139 
3140  $langs->load("user");
3141 
3142  // Positionne le modele sur le nom du modele a utiliser
3143  if (! dol_strlen($modele))
3144  {
3145  if (! empty($conf->global->USER_ADDON_PDF))
3146  {
3147  $modele = $conf->global->USER_ADDON_PDF;
3148  }
3149  else
3150  {
3151  $modele = 'bluesky';
3152  }
3153  }
3154 
3155  $modelpath = "core/modules/user/doc/";
3156 
3157  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3158  }
3159 
3160  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3168  function user_get_property($rowid,$mode)
3169  {
3170  // phpcs:enable
3171  $user_property='';
3172 
3173  if (empty($rowid)) return '';
3174 
3175  $sql = "SELECT rowid, email, user_mobile, civility, lastname, firstname";
3176  $sql.= " FROM ".MAIN_DB_PREFIX."user";
3177  $sql.= " WHERE rowid = '".$rowid."'";
3178 
3179  $resql=$this->db->query($sql);
3180  if ($resql)
3181  {
3182  $nump = $this->db->num_rows($resql);
3183 
3184  if ($nump)
3185  {
3186  $obj = $this->db->fetch_object($resql);
3187 
3188  if ($mode == 'email') $user_property = dolGetFirstLastname($obj->firstname, $obj->lastname)." <".$obj->email.">";
3189  else if ($mode == 'mobile') $user_property = $obj->user_mobile;
3190  }
3191  return $user_property;
3192  }
3193  else
3194  {
3195  dol_print_error($this->db);
3196  }
3197  }
3198 
3210  function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter=array(), $filtermode='AND')
3211  {
3212  global $conf;
3213 
3214  $sql="SELECT t.rowid";
3215  $sql.= ' FROM '.MAIN_DB_PREFIX .$this->table_element.' as t ';
3216  $sql.= " WHERE 1";
3217 
3218  // Manage filter
3219  $sqlwhere = array();
3220  if (!empty($filter)){
3221  foreach($filter as $key => $value) {
3222  if ($key=='t.rowid') {
3223  $sqlwhere[] = $key . '='. $value;
3224  }
3225  elseif (strpos($key,'date') !== false) {
3226  $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
3227  }
3228  elseif ($key=='customsql') {
3229  $sqlwhere[] = $value;
3230  }
3231  else {
3232  $sqlwhere[] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\'';
3233  }
3234  }
3235  }
3236  if (count($sqlwhere) > 0) {
3237  $sql .= ' AND (' . implode(' '.$filtermode.' ', $sqlwhere).')';
3238  }
3239  $sql.= $this->db->order($sortfield,$sortorder);
3240  if ($limit) $sql.= $this->db->plimit($limit+1,$offset);
3241 
3242  dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
3243 
3244  $resql=$this->db->query($sql);
3245  if ($resql)
3246  {
3247  $this->users=array();
3248  $num = $this->db->num_rows($resql);
3249  if ($num)
3250  {
3251  while ($obj = $this->db->fetch_object($resql))
3252  {
3253  $line = new self($this->db);
3254  $result = $line->fetch($obj->rowid);
3255  if ($result>0 && !empty($line->id)) {
3256  $this->users[$obj->rowid] = clone $line;
3257  }
3258  }
3259  $this->db->free($resql);
3260  }
3261  return $num;
3262  }
3263  else
3264  {
3265  $this->errors[] = $this->db->lasterror();
3266  return -1;
3267  }
3268  }
3269 }
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&#39;arborescence hierarchique des users sous la forme d&#39;un tableau Set and return this->use...
loadParentOf()
Load this->parentof that is array(id_son=>id_parent, ...)
user_get_property($rowid, $mode)
Return property of user from its id.
__construct($db)
Constructor of the class.
Definition: user.class.php:188
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.
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.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter=array(), $filtermode='AND')
Load all objects into $this->users.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding &#39;...&#39; if string larger than length.
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:1053
update_ldap2dolibarr(&$ldapuser)
Update user using data from the LDAP.
getLibStatut($mode=0)
Return label of status of user (active, inactive)
picto_from_langcode($codelang, $moreatt='')
Return img flag of country for a language code or country code.
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:292
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).
if(! empty($search_group)) natural_search(array("g.nom" g note
Definition: list.php:123
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:41
Class to manage Dolibarr database access.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
static showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0, $forcecapture='')
Return HTML code to output a photo.
update_clicktodial()
Update clicktodial info.
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+&#39; &#39;+name+&#39; &#39;+lastname)
get_children()
Return and array with all instanciated first level children users of current user.
$contact_id
Definition: user.class.php:122
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:630
info($id)
Load info of user object.
getNbOfUsers($limitTo, $option='', $admin=-1)
Return number of existing users.
setstatus($statut)
Change status of a user.
Definition: user.class.php:922
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.
loadDefaultValues()
Load default value in property ->default_values.
Definition: user.class.php:442
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.
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:107
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...
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0)
Clean a string from all HTML tags and entities.
getRandomPassword($generic=false)
Return a generated password using default module.
_load_ldap_dn($info, $mode=0)
Retourne chaine DN complete dans l&#39;annuaire LDAP pour l&#39;objet.
$societe_id
If this is defined, it is an external user.
Definition: user.class.php:117
setCategories($categories)
Sets object to supplied categories.
Definition: user.class.php:971
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:748
addrights($rid, $allmodule='', $allperms='', $entity=0, $notrigger=0)
Add a right to the user.
Definition: user.class.php:504
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
fetch($id='', $login='', $sid='', $loadpersonalconf=0, $entity=-1)
Load a user from database with its id or ref (login).
Definition: user.class.php:222
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&#39;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.
getrights($moduletag='', $forcereload=0)
Load permissions granted to user into object user.
Definition: user.class.php:765
$pass
Clear password in memory.
Definition: user.class.php:103
send_password($user, $password='', $changelater=0)
Send new password by email.
getNbOfEMailings()
Return number of mass Emailing received by this contacts with its email.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it&#39;s its name (generic function)
$pass_indatabase
Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
Definition: user.class.php:105
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&#39;un utilisateur Fonction appelee lors d&#39;une nou...
getPhotoUrl($width, $height, $cssclass='', $imagesize='')
Return a link with photo Use this->id,this->photo.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
getLoginUrl($withpicto=0, $option='')
Return clickable link of login (eventualy with picto)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
error()
Renvoie la derniere erreur fonctionnelle de manipulation de l&#39;objet.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
Class to manage warehouses.