dolibarr  20.0.0-beta
adherent.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2003 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) 2009-2017 Regis Houssin <regis.houssin@inodbox.com>
8  * Copyright (C) 2014-2018 Alexandre Spangaro <aspangaro@open-dsi.fr>
9  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
10  * Copyright (C) 2015-2024 Frédéric France <frederic.france@free.fr>
11  * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
12  * Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
13  * Copyright (C) 2018-2019 Thibault FOUCART <support@ptibogxiv.net>
14  * Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
15  * Copyright (C) 2020 Josep Lluís Amador <joseplluis@lliuretic.cat>
16  * Copyright (C) 2021 Waël Almoman <info@almoman.com>
17  * Copyright (C) 2021 Philippe Grand <philippe.grand@atoo-net.com>
18  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
19  *
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License as published by
22  * the Free Software Foundation; either version 3 of the License, or
23  * (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program. If not, see <https://www.gnu.org/licenses/>.
32  */
33 
39 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
41 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/core/class/commonpeople.class.php';
43 
44 
48 class Adherent extends CommonObject
49 {
50  use CommonPeople;
51 
55  public $element = 'member';
56 
60  public $table_element = 'adherent';
61 
65  public $picto = 'member';
66 
70  public $mesgs;
71 
75  public $login;
76 
80  public $pass;
81 
85  public $pass_indatabase;
86 
90  public $pass_indatabase_crypted;
91 
95  public $fullname;
96 
102  public $civility_id;
103 
107  public $civility_code;
108 
109  public $civility;
110 
116  public $societe;
117 
121  public $company;
122 
128  public $fk_soc;
129 
133  public $socid;
134 
138  public $socialnetworks;
139 
143  public $phone;
144 
148  public $phone_perso;
149 
153  public $phone_pro;
154 
158  public $phone_mobile;
159 
163  public $fax;
164 
168  public $poste;
169 
173  public $morphy;
174 
178  public $public;
179 
184  public $default_lang;
185 
189  public $photo;
190 
196  public $datec;
197 
203  public $datem;
204 
205  public $datevalid;
206 
210  public $gender;
211 
215  public $birth;
216 
220  public $typeid;
221 
225  public $type;
226 
230  public $need_subscription;
231 
235  public $user_id;
236 
240  public $user_login;
241 
242  public $datefin;
243 
244 
245  // Fields loaded by fetch_subscriptions() from member table
246 
250  public $first_subscription_date;
251 
255  public $first_subscription_date_start;
256 
260  public $first_subscription_date_end;
261 
265  public $first_subscription_amount;
266 
270  public $last_subscription_date;
271 
275  public $last_subscription_date_start;
276 
280  public $last_subscription_date_end;
281 
285  public $last_subscription_amount;
286 
290  public $subscriptions = array();
291 
295  public $ip;
296 
297  // Fields loaded by fetchPartnerships() from partnership table
298 
299  public $partnerships = array();
300 
304  public $invoice;
305 
306 
310  public $fields = array(
311  'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
312  'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
313  'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 15, 'index' => 1),
314  'ref_ext' => array('type' => 'varchar(128)', 'label' => 'Ref ext', 'enabled' => 1, 'visible' => 0, 'position' => 20),
315  'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
316  'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
317  'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
318  'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => 1, 'position' => 40),
319  'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => -1, 'position' => 45),
320  'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => -1, 'position' => 50),
321  'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
322  'fk_adherent_type' => array('type' => 'integer', 'label' => 'Fk adherent type', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
323  'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
324  'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
325  'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
326  'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
327  'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
328  'state_id' => array('type' => 'integer', 'label' => 'State id', 'enabled' => 1, 'visible' => -1, 'position' => 90),
329  'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
330  'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
331  'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
332  'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
333  'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
334  'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
335  'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => -1, 'position' => 128),
336  'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
337  'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
338  'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
339  'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 145),
340  'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
341  'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
342  'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
343  'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
344  'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
345  'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
346  'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
347  'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 180),
348  'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user mod', 'enabled' => 1, 'visible' => -1, 'position' => 185),
349  'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 190),
350  'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => -1, 'position' => 195),
351  'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 500, 'arrayofkeyval' => array(-1 => 'Draft', 1 => 'Validated', 0 => 'MemberStatusResiliatedShort', -2 => 'MemberStatusExcludedShort')),
352  'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
353  'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805)
354  );
355 
359  const STATUS_DRAFT = -1;
363  const STATUS_VALIDATED = 1;
367  const STATUS_RESILIATED = 0;
371  const STATUS_EXCLUDED = -2;
372 
373 
379  public function __construct($db)
380  {
381  $this->db = $db;
382  $this->statut = self::STATUS_DRAFT;
383  $this->status = self::STATUS_DRAFT;
384  // l'adherent n'est pas public par default
385  $this->public = 0;
386  $this->ismultientitymanaged = 1;
387  $this->isextrafieldmanaged = 1;
388  // les champs optionnels sont vides
389  $this->array_options = array();
390  }
391 
392 
393  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
412  public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
413  {
414  // phpcs:enable
415  dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
416 
417  return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
418  }
419 
437  public function sendEmail($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
438  {
439  global $conf, $langs;
440 
441  // Detect if message is HTML
442  if ($msgishtml == -1) {
443  $msgishtml = 0;
444  if (dol_textishtml($text, 0)) {
445  $msgishtml = 1;
446  }
447  }
448 
449  dol_syslog('sendEmail msgishtml='.$msgishtml);
450 
451  $texttosend = $this->makeSubstitution($text);
452  $subjecttosend = $this->makeSubstitution($subject);
453  if ($msgishtml) {
454  $texttosend = dol_htmlentitiesbr($texttosend);
455  }
456 
457  // Envoi mail confirmation
458  $from = $conf->email_from;
459  if (getDolGlobalString('ADHERENT_MAIL_FROM')) {
460  $from = getDolGlobalString('ADHERENT_MAIL_FROM');
461  }
462 
463  $trackid = 'mem'.$this->id;
464 
465  // Send email (substitutionarray must be done just before this)
466  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
467  $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
468  if ($mailfile->sendfile()) {
469  return 1;
470  } else {
471  $this->error = $langs->trans("ErrorFailedToSendMail", $from, $this->email).'. '.$mailfile->error;
472  return -1;
473  }
474  }
475 
476 
483  public function makeSubstitution($text)
484  {
485  global $langs;
486 
487  $birthday = dol_print_date($this->birth, 'day');
488 
489  $msgishtml = 0;
490  if (dol_textishtml($text, 1)) {
491  $msgishtml = 1;
492  }
493 
494  $infos = '';
495  if ($this->civility_id) {
496  $infos .= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
497  }
498  $infos .= $langs->transnoentities("id").": ".$this->id."\n";
499  $infos .= $langs->transnoentities("ref").": ".$this->ref."\n";
500  $infos .= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
501  $infos .= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
502  $infos .= $langs->transnoentities("Company").": ".$this->company."\n";
503  $infos .= $langs->transnoentities("Address").": ".$this->address."\n";
504  $infos .= $langs->transnoentities("Zip").": ".$this->zip."\n";
505  $infos .= $langs->transnoentities("Town").": ".$this->town."\n";
506  $infos .= $langs->transnoentities("Country").": ".$this->country."\n";
507  $infos .= $langs->transnoentities("EMail").": ".$this->email."\n";
508  $infos .= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
509  $infos .= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
510  $infos .= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
511  if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
512  $infos .= $langs->transnoentities("Login").": ".$this->login."\n";
513  $infos .= $langs->transnoentities("Password").": ".$this->pass."\n";
514  }
515  $infos .= $langs->transnoentities("Birthday").": ".$birthday."\n";
516  $infos .= $langs->transnoentities("Photo").": ".$this->photo."\n";
517  $infos .= $langs->transnoentities("Public").": ".yn($this->public);
518 
519  // Substitutions
520  $substitutionarray = array(
521  '__ID__' => $this->id,
522  '__REF__' => $this->ref,
523  '__MEMBER_ID__' => $this->id,
524  '__CIVILITY__' => $this->getCivilityLabel(),
525  '__FIRSTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->firstname) : ($this->firstname ? $this->firstname : ''),
526  '__LASTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->lastname) : ($this->lastname ? $this->lastname : ''),
527  '__FULLNAME__' => $msgishtml ? dol_htmlentitiesbr($this->getFullName($langs)) : $this->getFullName($langs),
528  '__COMPANY__' => $msgishtml ? dol_htmlentitiesbr($this->company) : ($this->company ? $this->company : ''),
529  '__ADDRESS__' => $msgishtml ? dol_htmlentitiesbr($this->address) : ($this->address ? $this->address : ''),
530  '__ZIP__' => $msgishtml ? dol_htmlentitiesbr($this->zip) : ($this->zip ? $this->zip : ''),
531  '__TOWN__' => $msgishtml ? dol_htmlentitiesbr($this->town) : ($this->town ? $this->town : ''),
532  '__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''),
533  '__EMAIL__' => $msgishtml ? dol_htmlentitiesbr($this->email) : ($this->email ? $this->email : ''),
534  '__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''),
535  '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($this->photo) : ($this->photo ? $this->photo : ''),
536  '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($this->login) : ($this->login ? $this->login : ''),
537  '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($this->pass) : ($this->pass ? $this->pass : ''),
538  '__PHONE__' => $msgishtml ? dol_htmlentitiesbr($this->phone) : ($this->phone ? $this->phone : ''),
539  '__PHONEPRO__' => $msgishtml ? dol_htmlentitiesbr($this->phone_perso) : ($this->phone_perso ? $this->phone_perso : ''),
540  '__PHONEMOBILE__' => $msgishtml ? dol_htmlentitiesbr($this->phone_mobile) : ($this->phone_mobile ? $this->phone_mobile : ''),
541  '__TYPE__' => $msgishtml ? dol_htmlentitiesbr($this->type) : ($this->type ? $this->type : '')
542  );
543 
544  complete_substitutions_array($substitutionarray, $langs, $this);
545 
546  return make_substitutions($text, $substitutionarray, $langs);
547  }
548 
549 
557  public function getmorphylib($morphy = '', $addbadge = 0)
558  {
559  global $langs;
560  $s = '';
561 
562  // Clean var
563  if (!$morphy) {
564  $morphy = $this->morphy;
565  }
566 
567  if ($addbadge) {
568  $labeltoshowm = $langs->trans("Moral");
569  $labeltoshowp = $langs->trans("Physical");
570  if ($morphy == 'phy') {
571  $labeltoshow = $labeltoshowp;
572  if ($addbadge == 2) {
573  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp));
574  if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowm))) {
575  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp, 2));
576  }
577  }
578  $s .= '<span class="member-individual-back paddingleftimp paddingrightimp" title="'.$langs->trans("Physical").'">'.$labeltoshow.'</span>';
579  }
580  if ($morphy == 'mor') {
581  $labeltoshow = $labeltoshowm;
582  if ($addbadge == 2) {
583  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm));
584  if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowp))) {
585  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm, 2));
586  }
587  }
588  $s .= '<span class="member-company-back paddingleftimp paddingrightimp" title="'.$langs->trans("Moral").'">'.$labeltoshow.'</span>';
589  }
590  } else {
591  if ($morphy == 'phy') {
592  $s = $langs->trans("Physical");
593  } elseif ($morphy == 'mor') {
594  $s = $langs->trans("Moral");
595  }
596  }
597 
598  return $s;
599  }
600 
608  public function create($user, $notrigger = 0)
609  {
610  global $conf, $langs, $mysoc;
611 
612  $error = 0;
613 
614  $now = dol_now();
615 
616  // Clean parameters
617  $this->import_key = trim($this->import_key);
618 
619  // Check parameters
620  if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
621  $langs->load("errors");
622  $this->error = $langs->trans("ErrorBadEMail", $this->email);
623  return -1;
624  }
625  if (!$this->datec) {
626  $this->datec = $now;
627  }
628  if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
629  if (empty($this->login)) {
630  $this->error = $langs->trans("ErrorWrongValueForParameterX", "Login");
631  return -1;
632  }
633  }
634 
635  $this->db->begin();
636 
637  // Insert member
638  $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
639  $sql .= " (ref, datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key, ip)";
640  $sql .= " VALUES (";
641  $sql .= " '(PROV)'";
642  $sql .= ", '".$this->db->idate($this->datec)."'";
643  $sql .= ", ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
644  $sql .= ", ".($user->id > 0 ? $user->id : "null"); // Can be null because member can be created by a guest or a script
645  $sql .= ", null, null, '".$this->db->escape($this->morphy)."'";
646  $sql .= ", ".((int) $this->typeid);
647  $sql .= ", ".$conf->entity;
648  $sql .= ", ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
649  $sql .= ", ".(!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
650  $sql .= ")";
651 
652  dol_syslog(get_class($this)."::create", LOG_DEBUG);
653  $result = $this->db->query($sql);
654  if ($result) {
655  $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
656  if ($id > 0) {
657  $this->id = $id;
658  if (getDolGlobalString('MEMBER_CODEMEMBER_ADDON') == '') {
659  // keep old numbering
660  $this->ref = (string) $id;
661  } else {
662  // auto code
663  $modfile = dol_buildpath('core/modules/member/'.getDolGlobalString('MEMBER_CODEMEMBER_ADDON').'.php', 0);
664  try {
665  require_once $modfile;
666  $modname = getDolGlobalString('MEMBER_CODEMEMBER_ADDON');
667  $modCodeMember = new $modname();
668  '@phan-var-force ModeleNumRefMembers $modCodeMember';
669  $this->ref = $modCodeMember->getNextValue($mysoc, $this);
670  } catch (Exception $e) {
671  dol_syslog($e->getMessage(), LOG_ERR);
672  $error++;
673  }
674  }
675 
676  // Update minor fields
677  $result = $this->update($user, 1, 1, 0, 0, 'add'); // nosync is 1 to avoid update data of user
678  if ($result < 0) {
679  $this->db->rollback();
680  return -1;
681  }
682 
683  // Add link to user
684  if ($this->user_id) {
685  // Add link to user
686  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
687  $sql .= " fk_member = ".((int) $this->id);
688  $sql .= " WHERE rowid = ".((int) $this->user_id);
689  dol_syslog(get_class($this)."::create", LOG_DEBUG);
690  $resql = $this->db->query($sql);
691  if (!$resql) {
692  $this->error = 'Failed to update user to make link with member';
693  $this->db->rollback();
694  return -4;
695  }
696  }
697 
698  if (!$notrigger) {
699  // Call trigger
700  $result = $this->call_trigger('MEMBER_CREATE', $user);
701  if ($result < 0) {
702  $error++;
703  }
704  // End call triggers
705  }
706 
707  if (count($this->errors)) {
708  dol_syslog(get_class($this)."::create ".implode(',', $this->errors), LOG_ERR);
709  $this->db->rollback();
710  return -3;
711  } else {
712  $this->db->commit();
713  return $this->id;
714  }
715  } else {
716  $this->error = 'Failed to get last insert id';
717  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
718  $this->db->rollback();
719  return -2;
720  }
721  } else {
722  $this->error = $this->db->error();
723  $this->db->rollback();
724  return -1;
725  }
726  }
727 
728 
740  public function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
741  {
742  global $langs, $hookmanager;
743 
744  require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
745 
746  $nbrowsaffected = 0;
747  $error = 0;
748 
749  dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
750 
751  // Clean parameters
752  $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
753  $this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
754  $this->gender = trim($this->gender);
755  // $this->address = ($this->address ? $this->address : $this->address);
756  // $this->zip = ($this->zip ? $this->zip : $this->zip);
757  // $this->town = ($this->town ? $this->town : $this->town);
758  // $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
759  // $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id);
760  // $this->note_public = ($this->note_public ? $this->note_public : $this->note_public);
761  // $this->note_private = ($this->note_private ? $this->note_private : $this->note_private);
762  $this->url = $this->url ? clean_url($this->url, 0) : '';
763  $this->setUpperOrLowerCase();
764  // Check parameters
765  if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
766  $langs->load("errors");
767  $this->error = $langs->trans("ErrorBadEMail", $this->email);
768  return -1;
769  }
770 
771  $this->db->begin();
772 
773  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
774  $sql .= " ref = '".$this->db->escape($this->ref)."'";
775  $sql .= ", civility = ".($this->civility_id ? "'".$this->db->escape($this->civility_id)."'" : "null");
776  $sql .= ", firstname = ".($this->firstname ? "'".$this->db->escape($this->firstname)."'" : "null");
777  $sql .= ", lastname = ".($this->lastname ? "'".$this->db->escape($this->lastname)."'" : "null");
778  $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
779  $sql .= ", login = ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
780  $sql .= ", societe = ".($this->company ? "'".$this->db->escape($this->company)."'" : ($this->societe ? "'".$this->db->escape($this->societe)."'" : "null"));
781  if ($this->socid) {
782  $sql .= ", fk_soc = ".($this->socid > 0 ? (int) $this->socid : "null"); // Must be modified only when creating from a third-party
783  }
784  $sql .= ", address = ".($this->address ? "'".$this->db->escape($this->address)."'" : "null");
785  $sql .= ", zip = ".($this->zip ? "'".$this->db->escape($this->zip)."'" : "null");
786  $sql .= ", town = ".($this->town ? "'".$this->db->escape($this->town)."'" : "null");
787  $sql .= ", country = ".($this->country_id > 0 ? (int) $this->country_id : "null");
788  $sql .= ", state_id = ".($this->state_id > 0 ? (int) $this->state_id : "null");
789  $sql .= ", email = '".$this->db->escape($this->email)."'";
790  $sql .= ", url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
791  $sql .= ", socialnetworks = ".($this->socialnetworks ? "'".$this->db->escape(json_encode($this->socialnetworks))."'" : "null");
792  $sql .= ", phone = ".($this->phone ? "'".$this->db->escape($this->phone)."'" : "null");
793  $sql .= ", phone_perso = ".($this->phone_perso ? "'".$this->db->escape($this->phone_perso)."'" : "null");
794  $sql .= ", phone_mobile = ".($this->phone_mobile ? "'".$this->db->escape($this->phone_mobile)."'" : "null");
795  $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
796  $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
797  $sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
798  $sql .= ", public = '".$this->db->escape($this->public)."'";
799  $sql .= ", statut = ".(int) $this->statut;
800  $sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
801  $sql .= ", fk_adherent_type = ".(int) $this->typeid;
802  $sql .= ", morphy = '".$this->db->escape($this->morphy)."'";
803  $sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null");
804 
805  if ($this->datefin) {
806  $sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
807  }
808  if ($this->datevalid) {
809  $sql .= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
810  }
811  $sql .= ", fk_user_mod = ".($user->id > 0 ? $user->id : 'null'); // Can be null because member can be create by a guest
812  $sql .= " WHERE rowid = ".((int) $this->id);
813 
814  // If we change the type of membership, we set also label of new type
815  if (!empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid) {
816  $sql2 = "SELECT libelle as label";
817  $sql2 .= " FROM ".MAIN_DB_PREFIX."adherent_type";
818  $sql2 .= " WHERE rowid = ".((int) $this->typeid);
819  $resql2 = $this->db->query($sql2);
820  if ($resql2) {
821  while ($obj = $this->db->fetch_object($resql2)) {
822  $this->type = $obj->label;
823  }
824  }
825  }
826 
827  dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
828  $resql = $this->db->query($sql);
829  if ($resql) {
830  unset($this->country_code);
831  unset($this->country);
832  unset($this->state_code);
833  unset($this->state);
834 
835  $nbrowsaffected += $this->db->affected_rows($resql);
836 
837  $action = 'update';
838 
839  // Actions on extra fields
840  if (!$error) {
841  $result = $this->insertExtraFields();
842  if ($result < 0) {
843  $error++;
844  }
845  }
846 
847  // Update password
848  if (!$error && $this->pass) {
849  dol_syslog(get_class($this)."::update update password");
850  if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) {
851  $isencrypted = getDolGlobalString('DATABASE_PWD_ENCRYPTED') ? 1 : 0;
852 
853  // If password to set differs from the one found into database
854  $result = $this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
855  if (!$nbrowsaffected) {
856  $nbrowsaffected++;
857  }
858  }
859  }
860 
861  // Remove links to user and replace with new one
862  if (!$error) {
863  dol_syslog(get_class($this)."::update update link to user");
864  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
865  dol_syslog(get_class($this)."::update", LOG_DEBUG);
866  $resql = $this->db->query($sql);
867  if (!$resql) {
868  $this->error = $this->db->error();
869  $this->db->rollback();
870  return -5;
871  }
872  // If there is a user linked to this member
873  if ($this->user_id > 0) {
874  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id)." WHERE rowid = ".((int) $this->user_id);
875  dol_syslog(get_class($this)."::update", LOG_DEBUG);
876  $resql = $this->db->query($sql);
877  if (!$resql) {
878  $this->error = $this->db->error();
879  $this->db->rollback();
880  return -5;
881  }
882  }
883  }
884 
885  if (!$error && $nbrowsaffected) { // If something has change in main data
886  // Update information on linked user if it is an update
887  if (!$error && $this->user_id > 0 && !$nosyncuser) {
888  require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
889 
890  dol_syslog(get_class($this)."::update update linked user");
891 
892  $luser = new User($this->db);
893  $result = $luser->fetch($this->user_id);
894 
895  if ($result >= 0) {
896  //var_dump($this->user_login);exit;
897  //var_dump($this->login);exit;
898 
899  // If option ADHERENT_LOGIN_NOT_REQUIRED is on, there is no login of member, so we do not overwrite user login to keep existing one.
900  if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
901  $luser->login = $this->login;
902  }
903 
904  $luser->ref = $this->ref;
905  $luser->civility_id = $this->civility_id;
906  $luser->firstname = $this->firstname;
907  $luser->lastname = $this->lastname;
908  $luser->gender = $this->gender;
909  $luser->pass = $this->pass;
910  //$luser->socid=$this->fk_soc; // We do not enable this. This may transform a user into an external user.
911 
912  $luser->birth = $this->birth;
913 
914  $luser->address = $this->address;
915  $luser->zip = $this->zip;
916  $luser->town = $this->town;
917  $luser->country_id = $this->country_id;
918  $luser->state_id = $this->state_id;
919 
920  $luser->email = $this->email;
921  $luser->socialnetworks = $this->socialnetworks;
922  $luser->office_phone = $this->phone;
923  $luser->user_mobile = $this->phone_mobile;
924 
925  $luser->lang = $this->default_lang;
926 
927  $luser->fk_member = $this->id;
928 
929  $result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
930  if ($result < 0) {
931  $this->error = $luser->error;
932  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
933  $error++;
934  }
935  } else {
936  $this->error = $luser->error;
937  $error++;
938  }
939  }
940 
941  // Update information on linked thirdparty if it is an update
942  if (!$error && $this->fk_soc > 0 && !$nosyncthirdparty) {
943  require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
944 
945  dol_syslog(get_class($this)."::update update linked thirdparty");
946 
947  // This member is linked with a thirdparty, so we also update thirdparty information
948  // if this is an update.
949  $lthirdparty = new Societe($this->db);
950  $result = $lthirdparty->fetch($this->fk_soc);
951 
952  if ($result > 0) {
953  $lthirdparty->address = $this->address;
954  $lthirdparty->zip = $this->zip;
955  $lthirdparty->town = $this->town;
956  $lthirdparty->email = $this->email;
957  $lthirdparty->socialnetworks = $this->socialnetworks;
958  $lthirdparty->phone = $this->phone;
959  $lthirdparty->state_id = $this->state_id;
960  $lthirdparty->country_id = $this->country_id;
961  //$lthirdparty->phone_mobile=$this->phone_mobile;
962  $lthirdparty->default_lang = $this->default_lang;
963 
964  $result = $lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
965 
966  if ($result < 0) {
967  $this->error = $lthirdparty->error;
968  $this->errors = $lthirdparty->errors;
969  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
970  $error++;
971  }
972  } elseif ($result < 0) {
973  $this->error = $lthirdparty->error;
974  $error++;
975  }
976  }
977  }
978 
979  if (!$error && !$notrigger) {
980  // Call trigger
981  $result = $this->call_trigger('MEMBER_MODIFY', $user);
982  if ($result < 0) {
983  $error++;
984  }
985  // End call triggers
986  }
987 
988  if (!$error) {
989  $this->db->commit();
990  return $nbrowsaffected;
991  } else {
992  $this->db->rollback();
993  return -1;
994  }
995  } else {
996  $this->db->rollback();
997  $this->error = $this->db->lasterror();
998  return -2;
999  }
1000  }
1001 
1002 
1003  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1011  public function update_end_date($user)
1012  {
1013  // phpcs:enable
1014  $this->db->begin();
1015 
1016  // Search for last subscription id and end date
1017  $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
1018  $sql .= " FROM ".MAIN_DB_PREFIX."subscription";
1019  $sql .= " WHERE fk_adherent = ".((int) $this->id);
1020  $sql .= " ORDER by dateadh DESC"; // Sort by start subscription date
1021 
1022  dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1023  $resql = $this->db->query($sql);
1024  if ($resql) {
1025  $obj = $this->db->fetch_object($resql);
1026  $dateop = $this->db->jdate($obj->dateop);
1027  $datedeb = $this->db->jdate($obj->datedeb);
1028  $datefin = $this->db->jdate($obj->datefin);
1029 
1030  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1031  $sql .= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
1032  $sql .= " WHERE rowid = ".((int) $this->id);
1033 
1034  dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1035  $resql = $this->db->query($sql);
1036  if ($resql) {
1037  $this->last_subscription_date = $dateop;
1038  $this->last_subscription_date_start = $datedeb;
1039  $this->last_subscription_date_end = $datefin;
1040  $this->datefin = $datefin;
1041  $this->db->commit();
1042  return 1;
1043  } else {
1044  $this->db->rollback();
1045  return -1;
1046  }
1047  } else {
1048  $this->error = $this->db->lasterror();
1049  $this->db->rollback();
1050  return -1;
1051  }
1052  }
1053 
1061  public function delete($user, $notrigger = 0)
1062  {
1063  $result = 0;
1064  $error = 0;
1065  $errorflag = 0;
1066 
1067  // Check parameters
1068  $rowid = $this->id;
1069 
1070  $this->db->begin();
1071 
1072  if (!$error && !$notrigger) {
1073  // Call trigger
1074  $result = $this->call_trigger('MEMBER_DELETE', $user);
1075  if ($result < 0) {
1076  $error++;
1077  }
1078  // End call triggers
1079  }
1080 
1081  // Remove category
1082  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".((int) $rowid);
1083  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1084  $resql = $this->db->query($sql);
1085  if (!$resql) {
1086  $error++;
1087  $this->error .= $this->db->lasterror();
1088  $errorflag = -1;
1089  }
1090 
1091  // Remove subscription
1092  if (!$error) {
1093  $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".((int) $rowid);
1094  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1095  $resql = $this->db->query($sql);
1096  if (!$resql) {
1097  $error++;
1098  $this->error .= $this->db->lasterror();
1099  $errorflag = -2;
1100  }
1101  }
1102 
1103  // Remove linked user
1104  if (!$error) {
1105  $ret = $this->setUserId(0);
1106  if ($ret < 0) {
1107  $error++;
1108  $this->error .= $this->db->lasterror();
1109  $errorflag = -3;
1110  }
1111  }
1112 
1113  // Removed extrafields
1114  if (!$error) {
1115  $result = $this->deleteExtraFields();
1116  if ($result < 0) {
1117  $error++;
1118  $errorflag = -4;
1119  dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
1120  }
1121  }
1122 
1123  // Remove adherent
1124  if (!$error) {
1125  $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".((int) $rowid);
1126  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1127  $resql = $this->db->query($sql);
1128  if (!$resql) {
1129  $error++;
1130  $this->error .= $this->db->lasterror();
1131  $errorflag = -5;
1132  }
1133  }
1134 
1135  if (!$error) {
1136  $this->db->commit();
1137  return 1;
1138  } else {
1139  $this->db->rollback();
1140  return $errorflag;
1141  }
1142  }
1143 
1144 
1155  public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
1156  {
1157  global $conf, $langs;
1158 
1159  $error = 0;
1160 
1161  dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." isencrypted=".$isencrypted);
1162 
1163  // If new password not provided, we generate one
1164  if (!$password) {
1165  require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
1166  $password = getRandomPassword(false);
1167  }
1168 
1169  // Crypt password
1170  $password_crypted = dol_hash($password);
1171 
1172  $password_indatabase = '';
1173  if (!$isencrypted) {
1174  $password_indatabase = $password;
1175  }
1176 
1177  $this->db->begin();
1178 
1179  // Mise a jour
1180  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
1181  $sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
1182  if ($isencrypted) {
1183  $sql .= ", pass = null";
1184  } else {
1185  $sql .= ", pass = '".$this->db->escape($password_indatabase)."'";
1186  }
1187  $sql .= " WHERE rowid = ".((int) $this->id);
1188 
1189  //dol_syslog("Adherent::Password sql=hidden");
1190  dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1191  $result = $this->db->query($sql);
1192  if ($result) {
1193  $nbaffectedrows = $this->db->affected_rows($result);
1194 
1195  if ($nbaffectedrows) {
1196  $this->pass = $password;
1197  $this->pass_indatabase = $password_indatabase;
1198  $this->pass_indatabase_crypted = $password_crypted;
1199 
1200  if ($this->user_id && !$nosyncuser) {
1201  require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1202 
1203  // This member is linked with a user, so we also update users information
1204  // if this is an update.
1205  $luser = new User($this->db);
1206  $result = $luser->fetch($this->user_id);
1207 
1208  if ($result >= 0) {
1209  $result = $luser->setPassword($user, $this->pass, 0, 0, 1);
1210  if (is_int($result) && $result < 0) {
1211  $this->error = $luser->error;
1212  dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR);
1213  $error++;
1214  }
1215  } else {
1216  $this->error = $luser->error;
1217  $error++;
1218  }
1219  }
1220 
1221  if (!$error && !$notrigger) {
1222  // Call trigger
1223  $result = $this->call_trigger('MEMBER_NEW_PASSWORD', $user);
1224  if ($result < 0) {
1225  $error++;
1226  $this->db->rollback();
1227  return -1;
1228  }
1229  // End call triggers
1230  }
1231 
1232  $this->db->commit();
1233  return $this->pass;
1234  } else {
1235  $this->db->rollback();
1236  return 0;
1237  }
1238  } else {
1239  $this->db->rollback();
1240  dol_print_error($this->db);
1241  return -1;
1242  }
1243  }
1244 
1245 
1252  public function setUserId($userid)
1253  {
1254  global $conf, $langs;
1255 
1256  $this->db->begin();
1257 
1258  // If user is linked to this member, remove old link to this member
1259  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
1260  dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1261  $resql = $this->db->query($sql);
1262  if (!$resql) {
1263  $this->error = $this->db->error();
1264  $this->db->rollback();
1265  return -1;
1266  }
1267 
1268  // Set link to user
1269  if ($userid > 0) {
1270  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id);
1271  $sql .= " WHERE rowid = ".((int) $userid);
1272  dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1273  $resql = $this->db->query($sql);
1274  if (!$resql) {
1275  $this->error = $this->db->error();
1276  $this->db->rollback();
1277  return -2;
1278  }
1279  }
1280 
1281  $this->db->commit();
1282 
1283  return 1;
1284  }
1285 
1286 
1293  public function setThirdPartyId($thirdpartyid)
1294  {
1295  global $conf, $langs;
1296 
1297  $this->db->begin();
1298 
1299  // Remove link to third party onto any other members
1300  if ($thirdpartyid > 0) {
1301  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
1302  $sql .= " WHERE fk_soc = ".((int) $thirdpartyid);
1303  $sql .= " AND entity = ".$conf->entity;
1304  dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1305  $resql = $this->db->query($sql);
1306  }
1307 
1308  // Add link to third party for current member
1309  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid > 0 ? (int) $thirdpartyid : 'null');
1310  $sql .= " WHERE rowid = ".((int) $this->id);
1311 
1312  dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1313  $resql = $this->db->query($sql);
1314  if ($resql) {
1315  $this->db->commit();
1316  return 1;
1317  } else {
1318  $this->error = $this->db->error();
1319  $this->db->rollback();
1320  return -1;
1321  }
1322  }
1323 
1324 
1325  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1332  public function fetch_login($login)
1333  {
1334  // phpcs:enable
1335  global $conf;
1336 
1337  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1338  $sql .= " WHERE login='".$this->db->escape($login)."'";
1339  $sql .= " AND entity = ".$conf->entity;
1340 
1341  $resql = $this->db->query($sql);
1342  if ($resql) {
1343  if ($this->db->num_rows($resql)) {
1344  $obj = $this->db->fetch_object($resql);
1345  $this->fetch($obj->rowid);
1346  }
1347  } else {
1348  dol_print_error($this->db);
1349  }
1350  }
1351 
1352  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1360  public function fetch_name($firstname, $lastname)
1361  {
1362  // phpcs:enable
1363  global $conf;
1364 
1365  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1366  $sql .= " WHERE firstname='".$this->db->escape($firstname)."'";
1367  $sql .= " AND lastname='".$this->db->escape($lastname)."'";
1368  $sql .= " AND entity = ".$conf->entity;
1369 
1370  $resql = $this->db->query($sql);
1371  if ($resql) {
1372  if ($this->db->num_rows($resql)) {
1373  $obj = $this->db->fetch_object($resql);
1374  $this->fetch($obj->rowid);
1375  }
1376  } else {
1377  dol_print_error($this->db);
1378  }
1379  }
1380 
1392  public function fetch($rowid, $ref = '', $fk_soc = 0, $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
1393  {
1394  global $langs;
1395 
1396  $sql = "SELECT d.rowid, d.ref, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname,";
1397  $sql .= " d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1398  $sql .= " d.note_public,";
1399  $sql .= " d.email, d.url, d.socialnetworks, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1400  $sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1401  $sql .= " d.datec as datec,";
1402  $sql .= " d.tms as datem,";
1403  $sql .= " d.datefin as datefin, d.default_lang,";
1404  $sql .= " d.birth as birthday,";
1405  $sql .= " d.datevalid as datev,";
1406  $sql .= " d.country,";
1407  $sql .= " d.state_id,";
1408  $sql .= " d.model_pdf,";
1409  $sql .= " c.rowid as country_id, c.code as country_code, c.label as country,";
1410  $sql .= " dep.nom as state, dep.code_departement as state_code,";
1411  $sql .= " t.libelle as type, t.subscription as subscription,";
1412  $sql .= " u.rowid as user_id, u.login as user_login";
1413  $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
1414  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
1415  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
1416  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
1417  $sql .= " WHERE d.fk_adherent_type = t.rowid";
1418  if ($rowid) {
1419  $sql .= " AND d.rowid=".((int) $rowid);
1420  } elseif ($ref || $fk_soc) {
1421  $sql .= " AND d.entity IN (".getEntity('adherent').")";
1422  if ($ref) {
1423  $sql .= " AND d.ref='".$this->db->escape($ref)."'";
1424  } elseif ($fk_soc > 0) {
1425  $sql .= " AND d.fk_soc=".((int) $fk_soc);
1426  }
1427  } elseif ($ref_ext) {
1428  $sql .= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
1429  }
1430 
1431  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1432  $resql = $this->db->query($sql);
1433  if ($resql) {
1434  if ($this->db->num_rows($resql)) {
1435  $obj = $this->db->fetch_object($resql);
1436 
1437  $this->entity = $obj->entity;
1438  $this->id = $obj->rowid;
1439  $this->ref = $obj->ref;
1440  $this->ref_ext = $obj->ref_ext;
1441 
1442  $this->civility_id = $obj->civility_code; // Bad. Kept for backward compatibility
1443  $this->civility_code = $obj->civility_code;
1444  $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : '';
1445 
1446  $this->firstname = $obj->firstname;
1447  $this->lastname = $obj->lastname;
1448  $this->gender = $obj->gender;
1449  $this->login = $obj->login;
1450  $this->societe = $obj->company;
1451  $this->company = $obj->company;
1452  $this->socid = $obj->fk_soc;
1453  $this->fk_soc = $obj->fk_soc; // For backward compatibility
1454  $this->address = $obj->address;
1455  $this->zip = $obj->zip;
1456  $this->town = $obj->town;
1457 
1458  $this->pass = $obj->pass;
1459  $this->pass_indatabase = $obj->pass;
1460  $this->pass_indatabase_crypted = $obj->pass_crypted;
1461 
1462  $this->state_id = $obj->state_id;
1463  $this->state_code = $obj->state_id ? $obj->state_code : '';
1464  $this->state = $obj->state_id ? $obj->state : '';
1465 
1466  $this->country_id = $obj->country_id;
1467  $this->country_code = $obj->country_code;
1468  if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) {
1469  $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
1470  } else {
1471  $this->country = $obj->country;
1472  }
1473 
1474  $this->phone = $obj->phone;
1475  $this->phone_perso = $obj->phone_perso;
1476  $this->phone_mobile = $obj->phone_mobile;
1477  $this->email = $obj->email;
1478  $this->url = $obj->url;
1479 
1480  $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1481 
1482  $this->photo = $obj->photo;
1483  $this->statut = $obj->statut;
1484  $this->status = $obj->statut;
1485  $this->public = $obj->public;
1486 
1487  $this->datec = $this->db->jdate($obj->datec);
1488  $this->date_creation = $this->db->jdate($obj->datec);
1489  $this->datem = $this->db->jdate($obj->datem);
1490  $this->date_modification = $this->db->jdate($obj->datem);
1491  $this->datefin = $this->db->jdate($obj->datefin);
1492  $this->datevalid = $this->db->jdate($obj->datev);
1493  $this->date_validation = $this->db->jdate($obj->datev);
1494  $this->birth = $this->db->jdate($obj->birthday);
1495 
1496  $this->default_lang = $obj->default_lang;
1497 
1498  $this->note_private = $obj->note_private;
1499  $this->note_public = $obj->note_public;
1500  $this->morphy = $obj->morphy;
1501 
1502  $this->typeid = $obj->fk_adherent_type;
1503  $this->type = $obj->type;
1504  $this->need_subscription = $obj->subscription;
1505 
1506  $this->user_id = $obj->user_id;
1507  $this->user_login = $obj->user_login;
1508 
1509  $this->model_pdf = $obj->model_pdf;
1510 
1511  // Retrieve all extrafield
1512  // fetch optionals attributes and labels
1513  if ($fetch_optionals) {
1514  $this->fetch_optionals();
1515  }
1516 
1517  // Load other properties
1518  if ($fetch_subscriptions) {
1519  $result = $this->fetch_subscriptions();
1520  }
1521 
1522  return $this->id;
1523  } else {
1524  return 0;
1525  }
1526  } else {
1527  $this->error = $this->db->lasterror();
1528  return -1;
1529  }
1530  }
1531 
1532 
1533  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1542  public function fetch_subscriptions()
1543  {
1544  // phpcs:enable
1545  global $langs;
1546 
1547  require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1548 
1549  $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
1550  $sql .= " c.tms as datem,";
1551  $sql .= " c.datec as datec,";
1552  $sql .= " c.dateadh as dateh,";
1553  $sql .= " c.datef as datef";
1554  $sql .= " FROM ".MAIN_DB_PREFIX."subscription as c";
1555  $sql .= " WHERE c.fk_adherent = ".((int) $this->id);
1556  $sql .= " ORDER BY c.dateadh";
1557  dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
1558 
1559  $resql = $this->db->query($sql);
1560  if ($resql) {
1561  $this->subscriptions = array();
1562 
1563  $i = 0;
1564  while ($obj = $this->db->fetch_object($resql)) {
1565  if ($i == 0) {
1566  $this->first_subscription_date = $this->db->jdate($obj->datec);
1567  $this->first_subscription_date_start = $this->db->jdate($obj->dateh);
1568  $this->first_subscription_date_end = $this->db->jdate($obj->datef);
1569  $this->first_subscription_amount = $obj->subscription;
1570  }
1571  $this->last_subscription_date = $this->db->jdate($obj->datec);
1572  $this->last_subscription_date_start = $this->db->jdate($obj->dateh);
1573  $this->last_subscription_date_end = $this->db->jdate($obj->datef);
1574  $this->last_subscription_amount = $obj->subscription;
1575 
1576  $subscription = new Subscription($this->db);
1577  $subscription->id = $obj->rowid;
1578  $subscription->fk_adherent = $obj->fk_adherent;
1579  $subscription->fk_type = $obj->fk_type;
1580  $subscription->amount = $obj->subscription;
1581  $subscription->note = $obj->note_public;
1582  $subscription->note_public = $obj->note_public;
1583  $subscription->fk_bank = $obj->fk_bank;
1584  $subscription->datem = $this->db->jdate($obj->datem);
1585  $subscription->datec = $this->db->jdate($obj->datec);
1586  $subscription->dateh = $this->db->jdate($obj->dateh);
1587  $subscription->datef = $this->db->jdate($obj->datef);
1588 
1589  $this->subscriptions[] = $subscription;
1590 
1591  $i++;
1592  }
1593  return 1;
1594  } else {
1595  $this->error = $this->db->error().' sql='.$sql;
1596  return -1;
1597  }
1598  }
1599 
1600 
1607  public function fetchPartnerships($mode)
1608  {
1609  global $langs;
1610 
1611  require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php';
1612 
1613 
1614  $this->partnerships[] = array();
1615 
1616  return 1;
1617  }
1618 
1619 
1635  public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
1636  {
1637  global $conf, $langs, $user;
1638 
1639  require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1640 
1641  $error = 0;
1642 
1643  // Clean parameters
1644  if (!$amount) {
1645  $amount = 0;
1646  }
1647 
1648  $this->db->begin();
1649 
1650  if ($datesubend) {
1651  $datefin = $datesubend;
1652  } else {
1653  // If no end date, end date = date + 1 year - 1 day
1654  $datefin = dol_time_plus_duree($date, 1, 'y');
1655  $datefin = dol_time_plus_duree($datefin, -1, 'd');
1656  }
1657 
1658  // Create subscription
1659  $subscription = new Subscription($this->db);
1660  $subscription->fk_adherent = $this->id;
1661  $subscription->dateh = $date; // Date of new subscription
1662  $subscription->datef = $datefin; // End data of new subscription
1663  $subscription->amount = $amount;
1664  $subscription->note = $label; // deprecated
1665  $subscription->note_public = $label;
1666  $subscription->fk_type = $fk_type;
1667 
1668  $rowid = $subscription->create($user);
1669  if ($rowid > 0) {
1670  // Update denormalized subscription end date (read database subscription to find values)
1671  // This will also update this->datefin
1672  $result = $this->update_end_date($user);
1673  if ($result > 0) {
1674  // Change properties of object (used by triggers)
1675  $this->last_subscription_date = dol_now();
1676  $this->last_subscription_date_start = $date;
1677  $this->last_subscription_date_end = $datefin;
1678  $this->last_subscription_amount = $amount;
1679  }
1680 
1681  if (!$error) {
1682  $this->db->commit();
1683  return $rowid;
1684  } else {
1685  $this->db->rollback();
1686  return -2;
1687  }
1688  } else {
1689  $this->setErrorsFromObject($subscription);
1690  $this->db->rollback();
1691  return -1;
1692  }
1693  }
1694 
1695 
1715  public function subscriptionComplementaryActions($subscriptionid, $option, $accountid, $datesubscription, $paymentdate, $operation, $label, $amount, $num_chq, $emetteur_nom = '', $emetteur_banque = '', $autocreatethirdparty = 0, $ext_payment_id = '', $ext_payment_site = '')
1716  {
1717  global $conf, $langs, $user, $mysoc;
1718 
1719  $error = 0;
1720 
1721  $this->invoice = null; // This will contains invoice if an invoice is created
1722 
1723  dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".
1724  $paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
1725 
1726  // Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
1727  if ($option == 'bankdirect' && $accountid) {
1728  require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1729 
1730  $acct = new Account($this->db);
1731  $result = $acct->fetch($accountid);
1732 
1733  $dateop = $paymentdate;
1734 
1735  $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, '', $user, $emetteur_nom, $emetteur_banque);
1736  if ($insertid > 0) {
1737  $inserturlid = $acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
1738  if ($inserturlid > 0) {
1739  // Update table subscription
1740  $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".((int) $insertid);
1741  $sql .= " WHERE rowid=".((int) $subscriptionid);
1742 
1743  dol_syslog("subscription::subscription", LOG_DEBUG);
1744  $resql = $this->db->query($sql);
1745  if (!$resql) {
1746  $error++;
1747  $this->error = $this->db->lasterror();
1748  $this->errors[] = $this->error;
1749  }
1750  } else {
1751  $error++;
1752  $this->setErrorsFromObject($acct);
1753  }
1754  } else {
1755  $error++;
1756  $this->setErrorsFromObject($acct);
1757  }
1758  }
1759 
1760  // If option chosen, we create invoice
1761  if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
1762  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1763  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
1764 
1765  $invoice = new Facture($this->db);
1766  $customer = new Societe($this->db);
1767 
1768  if (!$error) {
1769  if (!($this->fk_soc > 0)) { // If not yet linked to a company
1770  if ($autocreatethirdparty) {
1771  // Create a linked thirdparty to member
1772  $companyalias = '';
1773  $fullname = $this->getFullName($langs);
1774 
1775  if ($this->morphy == 'mor') {
1776  $companyname = $this->company;
1777  if (!empty($fullname)) {
1778  $companyalias = $fullname;
1779  }
1780  } else {
1781  $companyname = $fullname;
1782  if (!empty($this->company)) {
1783  $companyalias = $this->company;
1784  }
1785  }
1786 
1787  $result = $customer->create_from_member($this, $companyname, $companyalias);
1788  if ($result < 0) {
1789  $this->error = $customer->error;
1790  $this->errors = $customer->errors;
1791  $error++;
1792  } else {
1793  $this->fk_soc = $result;
1794  }
1795  } else {
1796  $langs->load("errors");
1797  $this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1798  $this->errors[] = $this->error;
1799  $error++;
1800  }
1801  }
1802  }
1803  if (!$error) {
1804  $result = $customer->fetch($this->fk_soc);
1805  if ($result <= 0) {
1806  $this->error = $customer->error;
1807  $this->errors = $customer->errors;
1808  $error++;
1809  }
1810  }
1811 
1812  if (!$error) {
1813  // Create draft invoice
1814  $invoice->type = Facture::TYPE_STANDARD;
1815  $invoice->cond_reglement_id = $customer->cond_reglement_id;
1816  if (empty($invoice->cond_reglement_id)) {
1817  $paymenttermstatic = new PaymentTerm($this->db);
1818  $invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
1819  if (empty($invoice->cond_reglement_id)) {
1820  $error++;
1821  $this->error = 'ErrorNoPaymentTermRECEPFound';
1822  $this->errors[] = $this->error;
1823  }
1824  }
1825  $invoice->socid = $this->fk_soc;
1826  //$invoice->date = $datesubscription;
1827  $invoice->date = dol_now();
1828 
1829  // Possibility to add external linked objects with hooks
1830  $invoice->linked_objects['subscription'] = $subscriptionid;
1831  if (GETPOSTISARRAY('other_linked_objects')) {
1832  $invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int'));
1833  }
1834 
1835  $result = $invoice->create($user);
1836  if ($result <= 0) {
1837  $this->error = $invoice->error;
1838  $this->errors = $invoice->errors;
1839  $error++;
1840  } else {
1841  $this->invoice = $invoice;
1842  }
1843  }
1844 
1845  if (!$error) {
1846  // Add line to draft invoice
1847  $idprodsubscription = 0;
1848  if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
1849  $idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
1850  }
1851 
1852  $vattouse = 0;
1853  if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
1854  $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
1855  }
1856  //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1857  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1858  $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, '', 'TTC', $amount, 1);
1859  if ($result <= 0) {
1860  $this->error = $invoice->error;
1861  $this->errors = $invoice->errors;
1862  $error++;
1863  }
1864  }
1865 
1866  if (!$error) {
1867  // Validate invoice
1868  $result = $invoice->validate($user);
1869  if ($result <= 0) {
1870  $this->error = $invoice->error;
1871  $this->errors = $invoice->errors;
1872  $error++;
1873  }
1874  }
1875 
1876  if (!$error) {
1877  // TODO Link invoice with subscription ?
1878  }
1879 
1880  // Add payment onto invoice
1881  if (!$error && $option == 'bankviainvoice' && $accountid) {
1882  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1883  require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1884  require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
1885 
1886  $amounts = array();
1887  $amounts[$invoice->id] = (float) price2num($amount);
1888 
1889  $paiement = new Paiement($this->db);
1890  $paiement->datepaye = $paymentdate;
1891  $paiement->amounts = $amounts;
1892  $paiement->paiementcode = $operation;
1893  $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
1894  $paiement->num_payment = $num_chq;
1895  $paiement->note_public = $label;
1896  $paiement->ext_payment_id = $ext_payment_id;
1897  $paiement->ext_payment_site = $ext_payment_site;
1898 
1899  if (!$error) {
1900  // Create payment line for invoice
1901  $paiement_id = $paiement->create($user);
1902  if (!($paiement_id > 0)) {
1903  $this->error = $paiement->error;
1904  $this->errors = $paiement->errors;
1905  $error++;
1906  }
1907  }
1908 
1909  if (!$error) {
1910  // Add transaction into bank account
1911  $bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
1912  if (!($bank_line_id > 0)) {
1913  $this->error = $paiement->error;
1914  $this->errors = $paiement->errors;
1915  $error++;
1916  }
1917  }
1918 
1919  if (!$error && !empty($bank_line_id)) {
1920  // Update fk_bank into subscription table
1921  $sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.((int) $bank_line_id);
1922  $sql .= ' WHERE rowid='.((int) $subscriptionid);
1923 
1924  $result = $this->db->query($sql);
1925  if (!$result) {
1926  $error++;
1927  }
1928  }
1929 
1930  if (!$error) {
1931  // Set invoice as paid
1932  $invoice->setPaid($user);
1933  }
1934  }
1935 
1936  if (!$error) {
1937  // Define output language
1938  $outputlangs = $langs;
1939  $newlang = '';
1940  $lang_id = GETPOST('lang_id');
1941  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
1942  $newlang = $lang_id;
1943  }
1944  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1945  $newlang = $customer->default_lang;
1946  }
1947  if (!empty($newlang)) {
1948  $outputlangs = new Translate("", $conf);
1949  $outputlangs->setDefaultLang($newlang);
1950  }
1951  // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
1952  //if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
1953 
1954  $invoice->generateDocument($invoice->model_pdf, $outputlangs);
1955  }
1956  }
1957 
1958  if ($error) {
1959  return -1;
1960  } else {
1961  return 1;
1962  }
1963  }
1964 
1965 
1972  public function validate($user)
1973  {
1974  global $langs, $conf;
1975 
1976  $error = 0;
1977  $now = dol_now();
1978 
1979  // Check parameters
1980  if ($this->statut == self::STATUS_VALIDATED) {
1981  dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
1982  return 0;
1983  }
1984 
1985  $this->db->begin();
1986 
1987  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1988  $sql .= " statut = ".self::STATUS_VALIDATED;
1989  $sql .= ", datevalid = '".$this->db->idate($now)."'";
1990  $sql .= ", fk_user_valid = ".((int) $user->id);
1991  $sql .= " WHERE rowid = ".((int) $this->id);
1992 
1993  dol_syslog(get_class($this)."::validate", LOG_DEBUG);
1994  $result = $this->db->query($sql);
1995  if ($result) {
1996  $this->statut = self::STATUS_VALIDATED;
1997 
1998  // Call trigger
1999  $result = $this->call_trigger('MEMBER_VALIDATE', $user);
2000  if ($result < 0) {
2001  $error++;
2002  $this->db->rollback();
2003  return -1;
2004  }
2005  // End call triggers
2006 
2007  $this->datevalid = $now;
2008 
2009  $this->db->commit();
2010  return 1;
2011  } else {
2012  $this->error = $this->db->error();
2013  $this->db->rollback();
2014  return -1;
2015  }
2016  }
2017 
2018 
2025  public function resiliate($user)
2026  {
2027  global $langs, $conf;
2028 
2029  $error = 0;
2030 
2031  // Check parameters
2032  if ($this->statut == self::STATUS_RESILIATED) {
2033  dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2034  return 0;
2035  }
2036 
2037  $this->db->begin();
2038 
2039  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2040  $sql .= " statut = ".self::STATUS_RESILIATED;
2041  $sql .= ", fk_user_valid=".$user->id;
2042  $sql .= " WHERE rowid = ".((int) $this->id);
2043 
2044  $result = $this->db->query($sql);
2045  if ($result) {
2046  $this->statut = self::STATUS_RESILIATED;
2047 
2048  // Call trigger
2049  $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2050  if ($result < 0) {
2051  $error++;
2052  $this->db->rollback();
2053  return -1;
2054  }
2055  // End call triggers
2056 
2057  $this->db->commit();
2058  return 1;
2059  } else {
2060  $this->error = $this->db->error();
2061  $this->db->rollback();
2062  return -1;
2063  }
2064  }
2065 
2075  public function exclude($user)
2076  {
2077  $error = 0;
2078 
2079  // Check parameters
2080  if ($this->statut == self::STATUS_EXCLUDED) {
2081  dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2082  return 0;
2083  }
2084 
2085  $this->db->begin();
2086 
2087  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2088  $sql .= " statut = ".self::STATUS_EXCLUDED;
2089  $sql .= ", fk_user_valid=".$user->id;
2090  $sql .= " WHERE rowid = ".((int) $this->id);
2091 
2092  $result = $this->db->query($sql);
2093  if ($result) {
2094  $this->statut = self::STATUS_EXCLUDED;
2095 
2096  // Call trigger
2097  $result = $this->call_trigger('MEMBER_EXCLUDE', $user);
2098  if ($result < 0) {
2099  $error++;
2100  $this->db->rollback();
2101  return -1;
2102  }
2103  // End call triggers
2104 
2105  $this->db->commit();
2106  return 1;
2107  } else {
2108  $this->error = $this->db->error();
2109  $this->db->rollback();
2110  return -1;
2111  }
2112  }
2113 
2114  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2120  public function add_to_abo()
2121  {
2122  // phpcs:enable
2123  global $langs;
2124 
2125  include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2126  $mailmanspip = new MailmanSpip($this->db);
2127 
2128  $err = 0;
2129 
2130  // mailman
2131  if (getDolGlobalString('ADHERENT_USE_MAILMAN') && isModEnabled('mailmanspip')) {
2132  $result = $mailmanspip->add_to_mailman($this);
2133 
2134  if ($result < 0) {
2135  if (!empty($mailmanspip->error)) {
2136  $this->errors[] = $mailmanspip->error;
2137  }
2138  $err += 1;
2139  }
2140  foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) {
2141  $langs->load("errors");
2142  $this->errors[] = $langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
2143  }
2144  foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) {
2145  $langs->load("mailmanspip");
2146  $this->mesgs[] = $langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
2147  }
2148  }
2149 
2150  // spip
2151  if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2152  $result = $mailmanspip->add_to_spip($this);
2153  if ($result < 0) {
2154  $this->errors[] = $mailmanspip->error;
2155  $err += 1;
2156  }
2157  }
2158  if ($err) {
2159  return -$err;
2160  } else {
2161  return 1;
2162  }
2163  }
2164 
2165 
2166  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2172  public function del_to_abo()
2173  {
2174  // phpcs:enable
2175  global $conf, $langs;
2176 
2177  include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2178  $mailmanspip = new MailmanSpip($this->db);
2179 
2180  $err = 0;
2181 
2182  // mailman
2183  if (getDolGlobalString('ADHERENT_USE_MAILMAN')) {
2184  $result = $mailmanspip->del_to_mailman($this);
2185  if ($result < 0) {
2186  if (!empty($mailmanspip->error)) {
2187  $this->errors[] = $mailmanspip->error;
2188  }
2189  $err += 1;
2190  }
2191 
2192  foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) {
2193  $langs->load("errors");
2194  $this->errors[] = $langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
2195  }
2196  foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) {
2197  $langs->load("mailmanspip");
2198  $this->mesgs[] = $langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
2199  }
2200  }
2201 
2202  if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2203  $result = $mailmanspip->del_to_spip($this);
2204  if ($result < 0) {
2205  $this->errors[] = $mailmanspip->error;
2206  $err += 1;
2207  }
2208  }
2209  if ($err) {
2210  // error
2211  return -$err;
2212  } else {
2213  return 1;
2214  }
2215  }
2216 
2217 
2223  public function getCivilityLabel()
2224  {
2225  global $langs;
2226  $langs->load("dict");
2227 
2228  $code = (empty($this->civility_id) ? '' : $this->civility_id);
2229  if (empty($code)) {
2230  return '';
2231  }
2232  return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
2233  }
2234 
2241  public function getTooltipContentArray($params)
2242  {
2243  global $langs;
2244 
2245  $langs->loadLangs(['members', 'companies']);
2246  $nofetch = !empty($params['nofetch']);
2247 
2248  $datas = array();
2249 
2250  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2251  $langs->load("users");
2252  return ['optimize' => $langs->trans("ShowUser")];
2253  }
2254  if (!empty($this->photo)) {
2255  $photo = '<div class="photointooltip floatright">';
2256  $photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1);
2257  $photo .= '</div>';
2258  $datas['photo'] = $photo;
2259  }
2260 
2261  $datas['divopen'] = '<div class="centpercent">';
2262  $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Member").'</u> '.$this->getLibStatut(4);
2263  if (!empty($this->morphy)) {
2264  $datas['picto'] .= '&nbsp;' . $this->getmorphylib('', 1);
2265  }
2266  if (!empty($this->ref)) {
2267  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
2268  }
2269  if (!empty($this->login)) {
2270  $datas['login'] = '<br><b>'.$langs->trans('Login').':</b> '.$this->login;
2271  }
2272  if (!empty($this->firstname) || !empty($this->lastname)) {
2273  $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
2274  }
2275  if (!empty($this->company)) {
2276  $datas['company'] = '<br><b>'.$langs->trans('Company').':</b> '.$this->company;
2277  }
2278  if (!empty($this->email)) {
2279  $datas['email'] = '<br><b>'.$langs->trans("EMail").':</b> '.$this->email;
2280  }
2281  $datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs);
2282  // show categories for this record only in ajax to not overload lists
2283  if (isModEnabled('category') && !$nofetch) {
2284  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
2285  $form = new Form($this->db);
2286  $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_MEMBER, 1);
2287  }
2288  $datas['divclose'] = '</div>';
2289 
2290  return $datas;
2291  }
2292 
2306  public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0)
2307  {
2308  global $conf, $langs, $hookmanager;
2309 
2310  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpictoimg) {
2311  $withpictoimg = 0;
2312  }
2313 
2314  $result = '';
2315  $linkstart = '';
2316  $linkend = '';
2317  $classfortooltip = 'classfortooltip';
2318  $dataparams = '';
2319  $params = [
2320  'id' => $this->id,
2321  'objecttype' => $this->element,
2322  'option' => $option,
2323  'nofetch' => 1,
2324  ];
2325  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
2326  $classfortooltip = 'classforajaxtooltip';
2327  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
2328  $label = '';
2329  } else {
2330  $label = implode($this->getTooltipContentArray($params));
2331  }
2332 
2333  $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.((int) $this->id);
2334  if ($option == 'subscription') {
2335  $url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.((int) $this->id);
2336  }
2337 
2338  if ($option != 'nolink') {
2339  // Add param to save lastsearch_values or not
2340  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2341  if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
2342  $add_save_lastsearch_values = 1;
2343  }
2344  if ($add_save_lastsearch_values) {
2345  $url .= '&save_lastsearch_values=1';
2346  }
2347  }
2348 
2349  $linkstart .= '<a href="'.$url.'"';
2350  $linkclose = "";
2351  if (empty($notooltip)) {
2352  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2353  $langs->load("users");
2354  $label = $langs->trans("ShowUser");
2355  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
2356  }
2357  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
2358  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
2359  }
2360 
2361  $linkstart .= $linkclose.'>';
2362  $linkend = '</a>';
2363 
2364  $result .= $linkstart;
2365 
2366  if ($withpictoimg) {
2367  $paddafterimage = '';
2368  if (abs($withpictoimg) == 1 || abs($withpictoimg) == 4) {
2369  $morecss .= ' paddingrightonly';
2370  }
2371  // Only picto
2372  if ($withpictoimg > 0) {
2373  $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1).'</span>';
2374  } else {
2375  // Picto must be a photo
2376  $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'"'.($paddafterimage ? ' '.$paddafterimage : '').'>';
2377  $picto .= Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.(($withpictoimg == -3 || $withpictoimg == -4) ? 'small' : ''), 'mini', 0, 1);
2378  $picto .= '</span>';
2379  }
2380  $result .= $picto;
2381  }
2382  if (($withpictoimg > -2 && $withpictoimg != 2) || $withpictoimg == -4) {
2383  if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2384  $result .= '<span class="nopadding valignmiddle'.((!isset($this->statut) || $this->statut) ? '' : ' strikefordisabled').
2385  ($morecss ? ' usertext'.$morecss : '').'">';
2386  }
2387  if ($mode == 'login') {
2388  $result .= dol_trunc($this->login, $maxlen);
2389  } elseif ($mode == 'ref') {
2390  $result .= $this->ref;
2391  } else {
2392  $result .= $this->getFullName($langs, '', ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2393  }
2394  if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2395  $result .= '</span>';
2396  }
2397  }
2398 
2399  $result .= $linkend;
2400 
2401  if ($addlinktonotes) {
2402  if ($this->note_private) {
2403  $notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($this->note_private, 1);
2404  $result .= ' <span class="note inline-block">';
2405  $result .= '<a href="'.DOL_URL_ROOT.'/adherents/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
2406  $result .= img_picto('', 'note');
2407  $result .= '</a>';
2408  $result .= '</span>';
2409  }
2410  }
2411  global $action;
2412  $hookmanager->initHooks(array($this->element . 'dao'));
2413  $parameters = array('id' => $this->id, 'getnomurl' => &$result);
2414  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2415  if ($reshook > 0) {
2416  $result = $hookmanager->resPrint;
2417  } else {
2418  $result .= $hookmanager->resPrint;
2419  }
2420  return $result;
2421  }
2422 
2429  public function getLibStatut($mode = 0)
2430  {
2431  return $this->LibStatut($this->statut, $this->need_subscription, $this->datefin, $mode);
2432  }
2433 
2434  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2444  public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
2445  {
2446  // phpcs:enable
2447  global $langs;
2448  $langs->load("members");
2449 
2450  $statusType = '';
2451  $labelStatus = '';
2452  $labelStatusShort = '';
2453 
2454  if ($status == self::STATUS_DRAFT) {
2455  $statusType = 'status0';
2456  $labelStatus = $langs->trans("MemberStatusDraft");
2457  $labelStatusShort = $langs->trans("MemberStatusDraftShort");
2458  } elseif ($status >= self::STATUS_VALIDATED) {
2459  if ($need_subscription === 0) {
2460  $statusType = 'status4';
2461  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusNoSubscription");
2462  $labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
2463  } elseif (!$date_end_subscription) {
2464  $statusType = 'status1';
2465  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("WaitingSubscription");
2466  $labelStatusShort = $langs->trans("WaitingSubscriptionShort");
2467  } elseif ($date_end_subscription < dol_now()) { // expired
2468  $statusType = 'status8';
2469  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusActiveLate");
2470  $labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
2471  } else {
2472  $statusType = 'status4';
2473  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusPaid");
2474  $labelStatusShort = $langs->trans("MemberStatusPaidShort");
2475  }
2476  } elseif ($status == self::STATUS_RESILIATED) {
2477  $statusType = 'status6';
2478  $labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
2479  $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
2480  } elseif ($status == self::STATUS_EXCLUDED) {
2481  $statusType = 'status10';
2482  $labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
2483  $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
2484  }
2485 
2486  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
2487  }
2488 
2489 
2495  public function loadStateBoard()
2496  {
2497  global $conf;
2498 
2499  $this->nb = array();
2500 
2501  $sql = "SELECT count(a.rowid) as nb";
2502  $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2503  $sql .= " WHERE a.statut > 0";
2504  $sql .= " AND a.entity IN (".getEntity('adherent').")";
2505 
2506  $resql = $this->db->query($sql);
2507  if ($resql) {
2508  while ($obj = $this->db->fetch_object($resql)) {
2509  $this->nb["members"] = $obj->nb;
2510  }
2511  $this->db->free($resql);
2512  return 1;
2513  } else {
2514  dol_print_error($this->db);
2515  $this->error = $this->db->error();
2516  return -1;
2517  }
2518  }
2519 
2520  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2528  public function load_board($user, $mode)
2529  {
2530  // phpcs:enable
2531  global $conf, $langs;
2532 
2533  if ($user->socid) {
2534  return -1; // protection pour eviter appel par utilisateur externe
2535  }
2536 
2537  $now = dol_now();
2538 
2539  $sql = "SELECT a.rowid, a.datefin, a.statut";
2540  $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2541  $sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
2542  $sql .= " WHERE a.fk_adherent_type = t.rowid";
2543  if ($mode == 'expired') {
2544  $sql .= " AND a.statut = ".self::STATUS_VALIDATED;
2545  $sql .= " AND a.entity IN (".getEntity('adherent').")";
2546  $sql .= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = '1')";
2547  } elseif ($mode == 'shift') {
2548  $sql .= " AND a.statut = ".self::STATUS_DRAFT;
2549  $sql .= " AND a.entity IN (".getEntity('adherent').")";
2550  }
2551 
2552  $resql = $this->db->query($sql);
2553  if ($resql) {
2554  $langs->load("members");
2555 
2556  $warning_delay = 0;
2557  $url = '';
2558  $label = '';
2559  $labelShort = '';
2560 
2561  if ($mode == 'expired') {
2562  $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2563  $label = $langs->trans("MembersWithSubscriptionToReceive");
2564  $labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
2565  $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_VALIDATED.'&amp;filter=outofdate';
2566  } elseif ($mode == 'shift') {
2567  $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2568  $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_DRAFT;
2569  $label = $langs->trans("MembersListToValid");
2570  $labelShort = $langs->trans("ToValidate");
2571  }
2572 
2573  $response = new WorkboardResponse();
2574  $response->warning_delay = $warning_delay;
2575  $response->label = $label;
2576  $response->labelShort = $labelShort;
2577  $response->url = $url;
2578  $response->img = img_object('', "user");
2579 
2580  $adherentstatic = new Adherent($this->db);
2581 
2582  while ($obj = $this->db->fetch_object($resql)) {
2583  $response->nbtodo++;
2584 
2585  $adherentstatic->datefin = $this->db->jdate($obj->datefin);
2586  $adherentstatic->statut = $obj->statut;
2587 
2588  if ($adherentstatic->hasDelay()) {
2589  $response->nbtodolate++;
2590  }
2591  }
2592 
2593  return $response;
2594  } else {
2595  dol_print_error($this->db);
2596  $this->error = $this->db->error();
2597  return -1;
2598  }
2599  }
2600 
2601 
2613  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2614  {
2615  global $conf, $langs;
2616 
2617  $langs->load("orders");
2618 
2619  if (!dol_strlen($modele)) {
2620  $modele = 'standard';
2621 
2622  if ($this->model_pdf) {
2623  $modele = $this->model_pdf;
2624  } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2625  $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2626  }
2627  }
2628 
2629  $modelpath = "core/modules/member/doc/";
2630 
2631  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2632  }
2633 
2634 
2642  public function initAsSpecimen()
2643  {
2644  global $user, $langs;
2645  $now = dol_now();
2646 
2647  // Initialise parameters
2648  $this->id = 0;
2649  $this->ref = 'ABC001';
2650  $this->entity = 1;
2651  $this->specimen = 1;
2652  $this->civility_id = 'MR';
2653  $this->lastname = 'DOLIBARR';
2654  $this->firstname = 'SPECIMEN';
2655  $this->gender = 'man';
2656  $this->login = 'dolibspec';
2657  $this->pass = 'dolibspec';
2658  $this->company = 'Societe ABC';
2659  $this->address = '61 jump street';
2660  $this->zip = '75000';
2661  $this->town = 'Paris';
2662  $this->country_id = 1;
2663  $this->country_code = 'FR';
2664  $this->country = 'France';
2665  $this->morphy = 'mor';
2666  $this->email = 'specimen@specimen.com';
2667  $this->socialnetworks = array(
2668  'skype' => 'skypepseudo',
2669  'twitter' => 'twitterpseudo',
2670  'facebook' => 'facebookpseudo',
2671  'linkedin' => 'linkedinpseudo',
2672  );
2673  $this->phone = '0999999999';
2674  $this->phone_perso = '0999999998';
2675  $this->phone_mobile = '0999999997';
2676  $this->note_public = 'This is a public note';
2677  $this->note_private = 'This is a private note';
2678  $this->birth = $now;
2679  $this->photo = '';
2680  $this->public = 1;
2681  $this->statut = self::STATUS_DRAFT;
2682 
2683  $this->datefin = $now;
2684  $this->datevalid = $now;
2685  $this->default_lang = '';
2686 
2687  $this->typeid = 1; // Id type adherent
2688  $this->type = 'Type adherent'; // Libelle type adherent
2689  $this->need_subscription = 0;
2690 
2691  $this->first_subscription_date = $now;
2692  $this->first_subscription_date_start = $this->first_subscription_date;
2693  $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2694  $this->first_subscription_amount = 10;
2695 
2696  $this->last_subscription_date = $this->first_subscription_date;
2697  $this->last_subscription_date_start = $this->first_subscription_date;
2698  $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2699  $this->last_subscription_amount = 10;
2700  return 1;
2701  }
2702 
2703 
2704  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2705  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2715  public function _load_ldap_dn($info, $mode = 0)
2716  {
2717  // phpcs:enable
2718  global $conf;
2719  $dn = '';
2720  if ($mode == 0) {
2721  $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')]."," . getDolGlobalString('LDAP_MEMBER_DN');
2722  }
2723  if ($mode == 1) {
2724  $dn = getDolGlobalString('LDAP_MEMBER_DN');
2725  }
2726  if ($mode == 2) {
2727  $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')];
2728  }
2729  return $dn;
2730  }
2731 
2732 
2733  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2734  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2740  public function _load_ldap_info()
2741  {
2742  // phpcs:enable
2743  global $conf, $langs;
2744 
2745  $info = array();
2746  $socialnetworks = getArrayOfSocialNetworks();
2747  $keymodified = false;
2748 
2749  // Object classes
2750  $info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
2751 
2752  $this->fullname = $this->getFullName($langs);
2753 
2754  // For avoid ldap error when firstname and lastname are empty
2755  if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
2756  $this->fullname = $this->company;
2757  $this->lastname = $this->company;
2758  }
2759 
2760  // Possible LDAP KEY (constname => varname)
2761  $ldapkey = array(
2762  'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
2763  'LDAP_MEMBER_FIELD_NAME' => 'lastname',
2764  'LDAP_MEMBER_FIELD_LOGIN' => 'login',
2765  'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
2766  'LDAP_MEMBER_FIELD_MAIL' => 'email'
2767  );
2768 
2769  // Member
2770  foreach ($ldapkey as $constname => $varname) {
2771  if (!empty($this->$varname) && getDolGlobalString($constname)) {
2772  $info[getDolGlobalString($constname)] = $this->$varname;
2773 
2774  // Check if it is the LDAP key and if its value has been changed
2775  if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
2776  if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
2777  $keymodified = true; // For check if LDAP key has been modified
2778  }
2779  }
2780  }
2781  }
2782  if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
2783  $info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
2784  }
2785  if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
2786  $info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
2787  }
2788  if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
2789  $info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
2790  }
2791  if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
2792  $info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
2793  }
2794  if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
2795  $info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
2796  }
2797  if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
2798  $info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
2799  }
2800  if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
2801  $info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
2802  }
2803  foreach ($socialnetworks as $key => $value) {
2804  if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))) {
2805  $info[getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
2806  }
2807  }
2808  if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
2809  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
2810  }
2811  if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
2812  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
2813  }
2814  if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
2815  $info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
2816  }
2817  if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
2818  $info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
2819  }
2820  if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
2821  $info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
2822  }
2823  if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
2824  $info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
2825  }
2826  if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
2827  $info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
2828  }
2829  if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
2830  $info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
2831  }
2832  if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
2833  $info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
2834  }
2835 
2836  // When password is modified
2837  if (!empty($this->pass)) {
2838  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2839  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
2840  }
2841  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2842  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2843  }
2844  } elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
2845  // Set LDAP password if possible
2846  // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2847  if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
2848  // Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
2849  if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
2850  if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2851  // Create OpenLDAP MD5 password from Dolibarr MD5 password
2852  // Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
2853  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
2854  }
2855  }
2856  } elseif (!empty($this->pass_indatabase)) {
2857  // Use $this->pass_indatabase value if exists
2858  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2859  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
2860  }
2861  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2862  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2863  }
2864  }
2865  }
2866 
2867  // Subscriptions
2868  if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
2869  $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
2870  }
2871  if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
2872  $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
2873  }
2874  if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
2875  $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
2876  }
2877  if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
2878  $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
2879  }
2880 
2881  return $info;
2882  }
2883 
2884 
2891  public function info($id)
2892  {
2893  $sql = 'SELECT a.rowid, a.datec as datec,';
2894  $sql .= ' a.datevalid as datev,';
2895  $sql .= ' a.tms as datem,';
2896  $sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2897  $sql .= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
2898  $sql .= ' WHERE a.rowid = '.((int) $id);
2899 
2900  dol_syslog(get_class($this)."::info", LOG_DEBUG);
2901  $result = $this->db->query($sql);
2902  if ($result) {
2903  if ($this->db->num_rows($result)) {
2904  $obj = $this->db->fetch_object($result);
2905 
2906  $this->id = $obj->rowid;
2907 
2908  $this->user_creation_id = $obj->fk_user_author;
2909  $this->user_validation_id = $obj->fk_user_valid;
2910  $this->user_modification_id = $obj->fk_user_mod;
2911  $this->date_creation = $this->db->jdate($obj->datec);
2912  $this->date_validation = $this->db->jdate($obj->datev);
2913  $this->date_modification = $this->db->jdate($obj->datem);
2914  }
2915 
2916  $this->db->free($result);
2917  } else {
2918  dol_print_error($this->db);
2919  }
2920  }
2921 
2927  public function getNbOfEMailings()
2928  {
2929  $sql = "SELECT count(mc.email) as nb";
2930  $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
2931  $sql .= " WHERE mc.email = '".$this->db->escape($this->email)."'";
2932  $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec success
2933 
2934  $resql = $this->db->query($sql);
2935  if ($resql) {
2936  $obj = $this->db->fetch_object($resql);
2937  $nb = $obj->nb;
2938 
2939  $this->db->free($resql);
2940  return $nb;
2941  } else {
2942  $this->error = $this->db->error();
2943  return -1;
2944  }
2945  }
2946 
2957  public function setCategories($categories)
2958  {
2959  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
2960  return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
2961  }
2962 
2971  public static function replaceThirdparty($db, $origin_id, $dest_id)
2972  {
2973  $tables = array('adherent');
2974 
2975  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
2976  }
2977 
2983  public function hasDelay()
2984  {
2985  global $conf;
2986 
2987  //Only valid members
2988  if ($this->statut != self::STATUS_VALIDATED) {
2989  return false;
2990  }
2991  if (!$this->datefin) {
2992  return false;
2993  }
2994 
2995  $now = dol_now();
2996 
2997  return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
2998  }
2999 
3000 
3008  public function sendReminderForExpiredSubscription($daysbeforeendlist = '10')
3009  {
3010  global $conf, $langs, $mysoc, $user;
3011 
3012  $error = 0;
3013  $this->output = '';
3014  $this->error = '';
3015 
3016  $blockingerrormsg = '';
3017 
3018  if (!isModEnabled('member')) { // Should not happen. If module disabled, cron job should not be visible.
3019  $langs->load("agenda");
3020  $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3021  return 0;
3022  }
3023  if (!getDolGlobalString('MEMBER_REMINDER_EMAIL')) {
3024  $langs->load("agenda");
3025  $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3026  return 0;
3027  }
3028 
3029  $now = dol_now();
3030  $nbok = 0;
3031  $nbko = 0;
3032 
3033  $listofmembersok = array();
3034  $listofmembersko = array();
3035 
3036  $arraydaysbeforeend = explode(';', $daysbeforeendlist);
3037  foreach ($arraydaysbeforeend as $daysbeforeend) { // Loop on each delay
3038  dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
3039 
3040  if (!is_numeric($daysbeforeend)) {
3041  $blockingerrormsg = "Value for delta is not a numeric value";
3042  $nbko++;
3043  break;
3044  }
3045 
3046  $tmp = dol_getdate($now);
3047  $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), $daysbeforeend, 'd');
3048 
3049  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
3050  $sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
3051  $sql .= " AND statut = 1";
3052  $sql .= " AND datefin = '".$this->db->idate($datetosearchfor)."'";
3053  //$sql .= " LIMIT 10000";
3054 
3055  $resql = $this->db->query($sql);
3056  if ($resql) {
3057  $num_rows = $this->db->num_rows($resql);
3058 
3059  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
3060  $adherent = new Adherent($this->db);
3061  $formmail = new FormMail($this->db);
3062 
3063  $i = 0;
3064  while ($i < $num_rows) {
3065  $obj = $this->db->fetch_object($resql);
3066 
3067  $adherent->fetch($obj->rowid, '', '', '', true, true);
3068 
3069  if (empty($adherent->email)) {
3070  $nbko++;
3071  $listofmembersko[$adherent->id] = $adherent->id;
3072  } else {
3073  $adherent->fetch_thirdparty();
3074 
3075  // Language code to use ($languagecodeformember) is default language of thirdparty, if no thirdparty, the language found from country of member then country of thirdparty, and if still not found we use the language of company.
3076  $languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : $adherent->thirdparty->country_code);
3077  $languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
3078 
3079  // Send reminder email
3080  $outputlangs = new Translate('', $conf);
3081  $outputlangs->setDefaultLang($languagecodeformember);
3082  $outputlangs->loadLangs(array("main", "members"));
3083  dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
3084 
3085  $arraydefaultmessage = null;
3086  $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
3087 
3088  if (!empty($labeltouse)) {
3089  $arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
3090  }
3091 
3092  if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
3093  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
3094  //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
3095  complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
3096 
3097  $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
3098  $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
3099  $from = getDolGlobalString('ADHERENT_MAIL_FROM');
3100  $to = $adherent->email;
3101  $cc = getDolGlobalString('ADHERENT_CC_MAIL_FROM');
3102 
3103  $trackid = 'mem'.$adherent->id;
3104  $moreinheader = 'X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
3105 
3106  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
3107  $cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), $cc, '', 0, 1, '', '', $trackid, $moreinheader);
3108  $result = $cmail->sendfile();
3109  if (!$result) {
3110  $error++;
3111  $this->error .= $cmail->error.' ';
3112  if (!is_null($cmail->errors)) {
3113  $this->errors += $cmail->errors;
3114  }
3115  $nbko++;
3116  $listofmembersko[$adherent->id] = $adherent->id;
3117  } else {
3118  $nbok++;
3119  $listofmembersok[$adherent->id] = $adherent->id;
3120 
3121  $message = $msg;
3122  $sendto = $to;
3123  $sendtocc = '';
3124  $sendtobcc = '';
3125  $actioncode = 'EMAIL';
3126  $extraparams = '';
3127 
3128  $actionmsg = '';
3129  $actionmsg2 = $langs->transnoentities('MailSentByTo', CMailFile::getValidAddress($from, 4, 0, 1), CMailFile::getValidAddress($sendto, 4, 0, 1));
3130  if ($message) {
3131  $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
3132  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
3133  if ($sendtocc) {
3134  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".dol_escape_htmltag($sendtocc));
3135  }
3136  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject);
3137  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":");
3138  $actionmsg = dol_concatdesc($actionmsg, $message);
3139  }
3140 
3141  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
3142 
3143  // Insert record of emails sent
3144  $actioncomm = new ActionComm($this->db);
3145 
3146  $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
3147  $actioncomm->code = 'AC_'.$actioncode;
3148  $actioncomm->label = $actionmsg2;
3149  $actioncomm->note_private = $actionmsg;
3150  $actioncomm->fk_project = 0;
3151  $actioncomm->datep = $now;
3152  $actioncomm->datef = $now;
3153  $actioncomm->percentage = -1; // Not applicable
3154  $actioncomm->socid = $adherent->thirdparty->id;
3155  $actioncomm->contact_id = 0;
3156  $actioncomm->authorid = $user->id; // User saving action
3157  $actioncomm->userownerid = $user->id; // Owner of action
3158  // Fields when action is en email (content should be added into note)
3159  $actioncomm->email_msgid = $cmail->msgid;
3160  $actioncomm->email_from = $from;
3161  $actioncomm->email_sender = '';
3162  $actioncomm->email_to = $to;
3163  $actioncomm->email_tocc = $sendtocc;
3164  $actioncomm->email_tobcc = $sendtobcc;
3165  $actioncomm->email_subject = $subject;
3166  $actioncomm->errors_to = '';
3167 
3168  $actioncomm->fk_element = $adherent->id;
3169  $actioncomm->elementtype = $adherent->element;
3170 
3171  $actioncomm->extraparams = $extraparams;
3172 
3173  $actioncomm->create($user);
3174  }
3175  } else {
3176  //$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
3177 
3178  $error++;
3179  $this->error .= "Can't find email template with label=".$labeltouse.", to use for the reminding email ";
3180 
3181  $nbko++;
3182  $listofmembersko[$adherent->id] = $adherent->id;
3183 
3184  break;
3185  }
3186  }
3187 
3188  $i++;
3189  }
3190  } else {
3191  $this->error = $this->db->lasterror();
3192  return 1;
3193  }
3194  }
3195 
3196  if ($blockingerrormsg) {
3197  $this->error = $blockingerrormsg;
3198  return 1;
3199  } else {
3200  $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
3201  $this->output .= ' Send email successfully to '.$nbok.' members';
3202  if (is_array($listofmembersok)) {
3203  $listofids = '';
3204  $i = 0;
3205  foreach ($listofmembersok as $idmember) {
3206  if ($i > 100) {
3207  $listofids .= ', ...';
3208  break;
3209  }
3210  if (empty($listofids)) {
3211  $listofids .= ' [';
3212  } else {
3213  $listofids .= ', ';
3214  }
3215  $listofids .= $idmember;
3216  $i++;
3217  }
3218  if ($listofids) {
3219  $listofids .= ']';
3220  }
3221 
3222  $this->output .= ($listofids ? ' ids='.$listofids : '');
3223  }
3224  if ($nbko) {
3225  $this->output .= ' - Canceled for '.$nbko.' member (no email or email sending error)';
3226  if (is_array($listofmembersko)) {
3227  $listofids = '';
3228  $i = 0;
3229  foreach ($listofmembersko as $idmember) {
3230  if ($i > 100) {
3231  $listofids .= ', ...';
3232  break;
3233  }
3234  if (empty($listofids)) {
3235  $listofids .= ' [';
3236  } else {
3237  $listofids .= ', ';
3238  }
3239  $listofids .= $idmember;
3240  $i++;
3241  }
3242  if ($listofids) {
3243  $listofids .= ']';
3244  }
3245  $this->output .= ($listofids ? ' ids='.$listofids : '');
3246  }
3247  }
3248  }
3249 
3250  return $nbko;
3251  }
3252 
3260  public function getKanbanView($option = '', $arraydata = null)
3261  {
3262  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
3263 
3264  $return = '<div class="box-flex-item box-flex-grow-zero">';
3265  $return .= '<div class="info-box info-box-sm">';
3266  $return .= '<span class="info-box-icon bg-infobox-action">';
3267  if (property_exists($this, 'photo') || !empty($this->photo)) {
3268  $return .= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photoref photowithmargin photologintooltip', 'small', 0, 1);
3269  } else {
3270  $return .= img_picto('', 'user');
3271  }
3272  $return .= '</span>';
3273  $return .= '<div class="info-box-content">';
3274  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
3275  if ($selected >= 0) {
3276  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
3277  }
3278  if (property_exists($this, 'type')) {
3279  $return .= '<br><span class="info-box-label opacitymedium">'.$this->type.'</span>';
3280  }
3281  if (method_exists($this, 'getmorphylib')) {
3282  $return .= '<br><span class="info-box-label">'.$this->getmorphylib('', 2).'</span>';
3283  }
3284  if (method_exists($this, 'getLibStatut')) {
3285  $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
3286  }
3287  $return .= '</div>';
3288  $return .= '</div>';
3289  $return .= '</div>';
3290  return $return;
3291  }
3292 }
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition: security.php:607
$object ref
Definition: info.php:79
Class to manage bank accounts.
Class to manage agenda events (actions)
Class to manage members of a foundation.
setThirdPartyId($thirdpartyid)
Set link to a third party.
hasDelay()
Return if a member is late (subscription late) or not.
exclude($user)
Functiun to exclude (set adherent.status to -2) a member TODO A private note should be added to know ...
add_to_abo()
Function to add member into external tools mailing-list, spip, etc.
loadStateBoard()
Load indicators this->nb in state board.
sendReminderForExpiredSubscription($daysbeforeendlist='10')
Send reminders by emails before subscription end CAN BE A CRON TASK.
_load_ldap_dn($info, $mode=0)
Retourne chaine DN complete dans l'annuaire LDAP pour l'objet.
update($user, $notrigger=0, $nosyncuser=0, $nosyncuserpass=0, $nosyncthirdparty=0, $action='update')
Update a member in database (standard information and password)
setCategories($categories)
Sets object to supplied categories.
getTooltipContentArray($params)
getTooltipContentArray
getNbOfEMailings()
Return number of mass Emailing received by this member with its email.
update_end_date($user)
Update denormalized last subscription date.
static replaceThirdparty($db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
subscriptionComplementaryActions($subscriptionid, $option, $accountid, $datesubscription, $paymentdate, $operation, $label, $amount, $num_chq, $emetteur_nom='', $emetteur_banque='', $autocreatethirdparty=0, $ext_payment_id='', $ext_payment_site='')
Do complementary actions after subscription recording.
makeSubstitution($text)
Make substitution of tags into text with value of current object.
const STATUS_EXCLUDED
Excluded.
LibStatut($status, $need_subscription, $date_end_subscription, $mode=0)
Renvoi le libelle d'un statut donne.
fetch_name($firstname, $lastname)
Method to load member from its name.
initAsSpecimen()
Initialise an instance with random values.
fetch($rowid, $ref='', $fk_soc=0, $ref_ext='', $fetch_optionals=true, $fetch_subscriptions=true)
Load member from database.
del_to_abo()
Function to delete a member from external tools like mailing-list, spip, etc.
resiliate($user)
Fonction qui resilie un adherent.
getCivilityLabel()
Return civility label of a member.
getmorphylib($morphy='', $addbadge=0)
Return translated label by the nature of a adherent (physical or moral)
sendEmail($text, $subject, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=-1, $errors_to='', $moreinheader='')
Function sending an email to the current member with the text supplied in parameter.
fetchPartnerships($mode)
Function to get partnerships array.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
setPassword($user, $password='', $isencrypted=0, $notrigger=0, $nosyncuser=0)
Change password of a user.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
const STATUS_DRAFT
Draft status.
const STATUS_RESILIATED
Resiliated.
fetch_login($login)
Method to load member from its login.
create($user, $notrigger=0)
Create a member into database.
_load_ldap_info()
Initialise tableau info (tableau des attributes LDAP)
getLibStatut($mode=0)
Retourne le libelle du statut d'un adherent (brouillon, valide, resilie, exclu)
info($id)
Load type info information in the member object.
__construct($db)
Constructor.
subscription($date, $amount, $accountid=0, $operation='', $label='', $num_chq='', $emetteur_nom='', $emetteur_banque='', $datesubend=0, $fk_type=null)
Insert subscription into database and eventually add links to banks, mailman, etc....
send_an_email($text, $subject, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=-1, $errors_to='', $moreinheader='')
Function sending an email to the current member with the text supplied in parameter.
getNomUrl($withpictoimg=0, $maxlen=0, $option='card', $mode='', $morecss='', $save_lastsearch_value=-1, $notooltip=0, $addlinktonotes=0)
Return clicable name (with picto eventually)
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
setUserId($userid)
Set link to a user.
const STATUS_VALIDATED
Validated status.
fetch_subscriptions()
Function to get member subscriptions data: subscriptions, first_subscription_date,...
validate($user)
Function that validate a member.
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
static getValidAddress($address, $format, $encode=0, $maxnumberofemail=0)
Return a formatted address string for SMTP protocol.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
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...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage invoices.
const TYPE_STANDARD
Standard invoice.
Class to manage generation of HTML components Only common components must be here.
static showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0, $forcecapture='', $noexternsourceoverwrite=0)
Return HTML code to output a photo.
Class permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new Form...
Class to manage mailman and spip.
Class to manage payments of customer invoices.
Class to manage payment terms records in dictionary.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage subscriptions of foundation members.
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:50
trait CommonPeople
Support class for thirdparties, contacts, members, users or resources.
getFullName($langs, $option=0, $nameorder=-1, $maxlen=0)
Return full name (civility+' '+name+' '+lastname)
setUpperOrLowerCase()
Set to upper or ucwords/lower if needed.
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:124
clean_url($url, $http=1)
Clean an url string.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
getLanguageCodeFromCountryCode($countrycode)
Return default language from country code.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_format_address($object, $withcountry=0, $sep="\n", $outputlangs=null, $mode=0, $extralangcode='')
Return a formatted address (part address/zip/town/state) according to country rules.
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
GETPOSTISARRAY($paramname, $method=0)
Return true if the parameter $paramname is submit from a POST OR GET as an array.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dolGetFirstLetters($s, $nbofchar=1)
Return first letters of a strings.
dol_strtoupper($string, $encoding="UTF-8")
Convert a string to upper.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
getArrayOfSocialNetworks()
Get array of social network dictionary.
dol_textishtml($msg, $option=0)
Return if a text is a html content.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
div float
Buy price without taxes.
Definition: style.css.php:960
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:123
getRandomPassword($generic=false, $replaceambiguouschars=null, $length=32)
Return a generated password using default module.
dolGetLdapPasswordHash($password, $type='md5')
Returns a specific ldap hash of a password.
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.