dolibarr  20.0.0-alpha
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 
66  public $ismultientitymanaged = 1;
67 
71  public $isextrafieldmanaged = 1;
72 
76  public $picto = 'member';
77 
81  public $mesgs;
82 
86  public $login;
87 
91  public $pass;
92 
96  public $pass_indatabase;
97 
101  public $pass_indatabase_crypted;
102 
106  public $fullname;
107 
113  public $civility_id;
114 
118  public $civility_code;
119 
120  public $civility;
121 
127  public $societe;
128 
132  public $company;
133 
139  public $fk_soc;
140 
144  public $socid;
145 
149  public $socialnetworks;
150 
154  public $phone;
155 
159  public $phone_perso;
160 
164  public $phone_pro;
165 
169  public $phone_mobile;
170 
174  public $fax;
175 
179  public $poste;
180 
184  public $morphy;
185 
189  public $public;
190 
195  public $default_lang;
196 
200  public $photo;
201 
207  public $datec;
208 
214  public $datem;
215 
216  public $datevalid;
217 
221  public $gender;
222 
226  public $birth;
227 
231  public $typeid;
232 
236  public $type;
237 
241  public $need_subscription;
242 
246  public $user_id;
247 
251  public $user_login;
252 
253  public $datefin;
254 
255 
256  // Fields loaded by fetch_subscriptions() from member table
257 
261  public $first_subscription_date;
262 
266  public $first_subscription_date_start;
267 
271  public $first_subscription_date_end;
272 
276  public $first_subscription_amount;
277 
281  public $last_subscription_date;
282 
286  public $last_subscription_date_start;
287 
291  public $last_subscription_date_end;
292 
296  public $last_subscription_amount;
297 
301  public $subscriptions = array();
302 
306  public $ip;
307 
308  // Fields loaded by fetchPartnerships() from partnership table
309 
310  public $partnerships = array();
311 
315  public $invoice;
316 
317 
321  public $fields = array(
322  'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
323  'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
324  'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 15, 'index' => 1),
325  'ref_ext' => array('type' => 'varchar(128)', 'label' => 'Ref ext', 'enabled' => 1, 'visible' => 0, 'position' => 20),
326  'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
327  'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
328  'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
329  'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => 1, 'position' => 40),
330  'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => -1, 'position' => 45),
331  'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => -1, 'position' => 50),
332  'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
333  'fk_adherent_type' => array('type' => 'integer', 'label' => 'Fk adherent type', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
334  'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
335  'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
336  'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
337  'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
338  'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
339  'state_id' => array('type' => 'integer', 'label' => 'State id', 'enabled' => 1, 'visible' => -1, 'position' => 90),
340  'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
341  'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
342  'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
343  'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
344  'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
345  'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
346  'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => -1, 'position' => 128),
347  'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
348  'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
349  'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
350  'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 145),
351  'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
352  'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
353  'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
354  'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
355  'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
356  'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
357  'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
358  'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 180),
359  'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user mod', 'enabled' => 1, 'visible' => -1, 'position' => 185),
360  'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 190),
361  'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => -1, 'position' => 195),
362  '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')),
363  'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
364  'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805)
365  );
366 
370  const STATUS_DRAFT = -1;
374  const STATUS_VALIDATED = 1;
378  const STATUS_RESILIATED = 0;
382  const STATUS_EXCLUDED = -2;
383 
384 
390  public function __construct($db)
391  {
392  $this->db = $db;
393  $this->statut = self::STATUS_DRAFT;
394  $this->status = self::STATUS_DRAFT;
395  // l'adherent n'est pas public par default
396  $this->public = 0;
397  // les champs optionnels sont vides
398  $this->array_options = array();
399  }
400 
401 
402  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
421  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 = '')
422  {
423  // phpcs:enable
424  dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
425 
426  return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
427  }
428 
446  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 = '')
447  {
448  global $conf, $langs;
449 
450  // Detect if message is HTML
451  if ($msgishtml == -1) {
452  $msgishtml = 0;
453  if (dol_textishtml($text, 0)) {
454  $msgishtml = 1;
455  }
456  }
457 
458  dol_syslog('sendEmail msgishtml='.$msgishtml);
459 
460  $texttosend = $this->makeSubstitution($text);
461  $subjecttosend = $this->makeSubstitution($subject);
462  if ($msgishtml) {
463  $texttosend = dol_htmlentitiesbr($texttosend);
464  }
465 
466  // Envoi mail confirmation
467  $from = $conf->email_from;
468  if (getDolGlobalString('ADHERENT_MAIL_FROM')) {
469  $from = getDolGlobalString('ADHERENT_MAIL_FROM');
470  }
471 
472  $trackid = 'mem'.$this->id;
473 
474  // Send email (substitutionarray must be done just before this)
475  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
476  $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
477  if ($mailfile->sendfile()) {
478  return 1;
479  } else {
480  $this->error = $langs->trans("ErrorFailedToSendMail", $from, $this->email).'. '.$mailfile->error;
481  return -1;
482  }
483  }
484 
485 
492  public function makeSubstitution($text)
493  {
494  global $langs;
495 
496  $birthday = dol_print_date($this->birth, 'day');
497 
498  $msgishtml = 0;
499  if (dol_textishtml($text, 1)) {
500  $msgishtml = 1;
501  }
502 
503  $infos = '';
504  if ($this->civility_id) {
505  $infos .= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
506  }
507  $infos .= $langs->transnoentities("id").": ".$this->id."\n";
508  $infos .= $langs->transnoentities("ref").": ".$this->ref."\n";
509  $infos .= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
510  $infos .= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
511  $infos .= $langs->transnoentities("Company").": ".$this->company."\n";
512  $infos .= $langs->transnoentities("Address").": ".$this->address."\n";
513  $infos .= $langs->transnoentities("Zip").": ".$this->zip."\n";
514  $infos .= $langs->transnoentities("Town").": ".$this->town."\n";
515  $infos .= $langs->transnoentities("Country").": ".$this->country."\n";
516  $infos .= $langs->transnoentities("EMail").": ".$this->email."\n";
517  $infos .= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
518  $infos .= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
519  $infos .= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
520  if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
521  $infos .= $langs->transnoentities("Login").": ".$this->login."\n";
522  $infos .= $langs->transnoentities("Password").": ".$this->pass."\n";
523  }
524  $infos .= $langs->transnoentities("Birthday").": ".$birthday."\n";
525  $infos .= $langs->transnoentities("Photo").": ".$this->photo."\n";
526  $infos .= $langs->transnoentities("Public").": ".yn($this->public);
527 
528  // Substitutions
529  $substitutionarray = array(
530  '__ID__' => $this->id,
531  '__REF__' => $this->ref,
532  '__MEMBER_ID__' => $this->id,
533  '__CIVILITY__' => $this->getCivilityLabel(),
534  '__FIRSTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->firstname) : ($this->firstname ? $this->firstname : ''),
535  '__LASTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->lastname) : ($this->lastname ? $this->lastname : ''),
536  '__FULLNAME__' => $msgishtml ? dol_htmlentitiesbr($this->getFullName($langs)) : $this->getFullName($langs),
537  '__COMPANY__' => $msgishtml ? dol_htmlentitiesbr($this->company) : ($this->company ? $this->company : ''),
538  '__ADDRESS__' => $msgishtml ? dol_htmlentitiesbr($this->address) : ($this->address ? $this->address : ''),
539  '__ZIP__' => $msgishtml ? dol_htmlentitiesbr($this->zip) : ($this->zip ? $this->zip : ''),
540  '__TOWN__' => $msgishtml ? dol_htmlentitiesbr($this->town) : ($this->town ? $this->town : ''),
541  '__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''),
542  '__EMAIL__' => $msgishtml ? dol_htmlentitiesbr($this->email) : ($this->email ? $this->email : ''),
543  '__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''),
544  '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($this->photo) : ($this->photo ? $this->photo : ''),
545  '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($this->login) : ($this->login ? $this->login : ''),
546  '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($this->pass) : ($this->pass ? $this->pass : ''),
547  '__PHONE__' => $msgishtml ? dol_htmlentitiesbr($this->phone) : ($this->phone ? $this->phone : ''),
548  '__PHONEPRO__' => $msgishtml ? dol_htmlentitiesbr($this->phone_perso) : ($this->phone_perso ? $this->phone_perso : ''),
549  '__PHONEMOBILE__' => $msgishtml ? dol_htmlentitiesbr($this->phone_mobile) : ($this->phone_mobile ? $this->phone_mobile : ''),
550  '__TYPE__' => $msgishtml ? dol_htmlentitiesbr($this->type) : ($this->type ? $this->type : '')
551  );
552 
553  complete_substitutions_array($substitutionarray, $langs, $this);
554 
555  return make_substitutions($text, $substitutionarray, $langs);
556  }
557 
558 
566  public function getmorphylib($morphy = '', $addbadge = 0)
567  {
568  global $langs;
569  $s = '';
570 
571  // Clean var
572  if (!$morphy) {
573  $morphy = $this->morphy;
574  }
575 
576  if ($addbadge) {
577  $labeltoshowm = $langs->trans("Moral");
578  $labeltoshowp = $langs->trans("Physical");
579  if ($morphy == 'phy') {
580  $labeltoshow = $labeltoshowp;
581  if ($addbadge == 2) {
582  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp));
583  if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowm))) {
584  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp, 2));
585  }
586  }
587  $s .= '<span class="member-individual-back paddingleftimp paddingrightimp" title="'.$langs->trans("Physical").'">'.$labeltoshow.'</span>';
588  }
589  if ($morphy == 'mor') {
590  $labeltoshow = $labeltoshowm;
591  if ($addbadge == 2) {
592  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm));
593  if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowp))) {
594  $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm, 2));
595  }
596  }
597  $s .= '<span class="member-company-back paddingleftimp paddingrightimp" title="'.$langs->trans("Moral").'">'.$labeltoshow.'</span>';
598  }
599  } else {
600  if ($morphy == 'phy') {
601  $s = $langs->trans("Physical");
602  } elseif ($morphy == 'mor') {
603  $s = $langs->trans("Moral");
604  }
605  }
606 
607  return $s;
608  }
609 
617  public function create($user, $notrigger = 0)
618  {
619  global $conf, $langs, $mysoc;
620 
621  $error = 0;
622 
623  $now = dol_now();
624 
625  // Clean parameters
626  $this->import_key = trim($this->import_key);
627 
628  // Check parameters
629  if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
630  $langs->load("errors");
631  $this->error = $langs->trans("ErrorBadEMail", $this->email);
632  return -1;
633  }
634  if (!$this->datec) {
635  $this->datec = $now;
636  }
637  if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
638  if (empty($this->login)) {
639  $this->error = $langs->trans("ErrorWrongValueForParameterX", "Login");
640  return -1;
641  }
642  }
643 
644  $this->db->begin();
645 
646  // Insert member
647  $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
648  $sql .= " (ref, datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key, ip)";
649  $sql .= " VALUES (";
650  $sql .= " '(PROV)'";
651  $sql .= ", '".$this->db->idate($this->datec)."'";
652  $sql .= ", ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
653  $sql .= ", ".($user->id > 0 ? $user->id : "null"); // Can be null because member can be created by a guest or a script
654  $sql .= ", null, null, '".$this->db->escape($this->morphy)."'";
655  $sql .= ", ".((int) $this->typeid);
656  $sql .= ", ".$conf->entity;
657  $sql .= ", ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
658  $sql .= ", ".(!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
659  $sql .= ")";
660 
661  dol_syslog(get_class($this)."::create", LOG_DEBUG);
662  $result = $this->db->query($sql);
663  if ($result) {
664  $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
665  if ($id > 0) {
666  $this->id = $id;
667  if (getDolGlobalString('MEMBER_CODEMEMBER_ADDON') == '') {
668  // keep old numbering
669  $this->ref = (string) $id;
670  } else {
671  // auto code
672  $modfile = dol_buildpath('core/modules/member/'.getDolGlobalString('MEMBER_CODEMEMBER_ADDON').'.php', 0);
673  try {
674  require_once $modfile;
675  $modname = getDolGlobalString('MEMBER_CODEMEMBER_ADDON');
676  $modCodeMember = new $modname();
677  '@phan-var-force ModeleNumRefMembers $modCodeMember';
678  $this->ref = $modCodeMember->getNextValue($mysoc, $this);
679  } catch (Exception $e) {
680  dol_syslog($e->getMessage(), LOG_ERR);
681  $error++;
682  }
683  }
684 
685  // Update minor fields
686  $result = $this->update($user, 1, 1, 0, 0, 'add'); // nosync is 1 to avoid update data of user
687  if ($result < 0) {
688  $this->db->rollback();
689  return -1;
690  }
691 
692  // Add link to user
693  if ($this->user_id) {
694  // Add link to user
695  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
696  $sql .= " fk_member = ".((int) $this->id);
697  $sql .= " WHERE rowid = ".((int) $this->user_id);
698  dol_syslog(get_class($this)."::create", LOG_DEBUG);
699  $resql = $this->db->query($sql);
700  if (!$resql) {
701  $this->error = 'Failed to update user to make link with member';
702  $this->db->rollback();
703  return -4;
704  }
705  }
706 
707  if (!$notrigger) {
708  // Call trigger
709  $result = $this->call_trigger('MEMBER_CREATE', $user);
710  if ($result < 0) {
711  $error++;
712  }
713  // End call triggers
714  }
715 
716  if (count($this->errors)) {
717  dol_syslog(get_class($this)."::create ".implode(',', $this->errors), LOG_ERR);
718  $this->db->rollback();
719  return -3;
720  } else {
721  $this->db->commit();
722  return $this->id;
723  }
724  } else {
725  $this->error = 'Failed to get last insert id';
726  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
727  $this->db->rollback();
728  return -2;
729  }
730  } else {
731  $this->error = $this->db->error();
732  $this->db->rollback();
733  return -1;
734  }
735  }
736 
737 
749  public function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
750  {
751  global $langs, $hookmanager;
752 
753  require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
754 
755  $nbrowsaffected = 0;
756  $error = 0;
757 
758  dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
759 
760  // Clean parameters
761  $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
762  $this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
763  $this->gender = trim($this->gender);
764  // $this->address = ($this->address ? $this->address : $this->address);
765  // $this->zip = ($this->zip ? $this->zip : $this->zip);
766  // $this->town = ($this->town ? $this->town : $this->town);
767  // $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
768  // $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id);
769  // $this->note_public = ($this->note_public ? $this->note_public : $this->note_public);
770  // $this->note_private = ($this->note_private ? $this->note_private : $this->note_private);
771  $this->url = $this->url ? clean_url($this->url, 0) : '';
772  $this->setUpperOrLowerCase();
773  // Check parameters
774  if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
775  $langs->load("errors");
776  $this->error = $langs->trans("ErrorBadEMail", $this->email);
777  return -1;
778  }
779 
780  $this->db->begin();
781 
782  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
783  $sql .= " ref = '".$this->db->escape($this->ref)."'";
784  $sql .= ", civility = ".($this->civility_id ? "'".$this->db->escape($this->civility_id)."'" : "null");
785  $sql .= ", firstname = ".($this->firstname ? "'".$this->db->escape($this->firstname)."'" : "null");
786  $sql .= ", lastname = ".($this->lastname ? "'".$this->db->escape($this->lastname)."'" : "null");
787  $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
788  $sql .= ", login = ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
789  $sql .= ", societe = ".($this->company ? "'".$this->db->escape($this->company)."'" : ($this->societe ? "'".$this->db->escape($this->societe)."'" : "null"));
790  if ($this->socid) {
791  $sql .= ", fk_soc = ".($this->socid > 0 ? (int) $this->socid : "null"); // Must be modified only when creating from a third-party
792  }
793  $sql .= ", address = ".($this->address ? "'".$this->db->escape($this->address)."'" : "null");
794  $sql .= ", zip = ".($this->zip ? "'".$this->db->escape($this->zip)."'" : "null");
795  $sql .= ", town = ".($this->town ? "'".$this->db->escape($this->town)."'" : "null");
796  $sql .= ", country = ".($this->country_id > 0 ? (int) $this->country_id : "null");
797  $sql .= ", state_id = ".($this->state_id > 0 ? (int) $this->state_id : "null");
798  $sql .= ", email = '".$this->db->escape($this->email)."'";
799  $sql .= ", url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
800  $sql .= ", socialnetworks = ".($this->socialnetworks ? "'".$this->db->escape(json_encode($this->socialnetworks))."'" : "null");
801  $sql .= ", phone = ".($this->phone ? "'".$this->db->escape($this->phone)."'" : "null");
802  $sql .= ", phone_perso = ".($this->phone_perso ? "'".$this->db->escape($this->phone_perso)."'" : "null");
803  $sql .= ", phone_mobile = ".($this->phone_mobile ? "'".$this->db->escape($this->phone_mobile)."'" : "null");
804  $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
805  $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
806  $sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
807  $sql .= ", public = '".$this->db->escape($this->public)."'";
808  $sql .= ", statut = ".(int) $this->statut;
809  $sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
810  $sql .= ", fk_adherent_type = ".(int) $this->typeid;
811  $sql .= ", morphy = '".$this->db->escape($this->morphy)."'";
812  $sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null");
813 
814  if ($this->datefin) {
815  $sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
816  }
817  if ($this->datevalid) {
818  $sql .= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
819  }
820  $sql .= ", fk_user_mod = ".($user->id > 0 ? $user->id : 'null'); // Can be null because member can be create by a guest
821  $sql .= " WHERE rowid = ".((int) $this->id);
822 
823  // If we change the type of membership, we set also label of new type
824  if (!empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid) {
825  $sql2 = "SELECT libelle as label";
826  $sql2 .= " FROM ".MAIN_DB_PREFIX."adherent_type";
827  $sql2 .= " WHERE rowid = ".((int) $this->typeid);
828  $resql2 = $this->db->query($sql2);
829  if ($resql2) {
830  while ($obj = $this->db->fetch_object($resql2)) {
831  $this->type = $obj->label;
832  }
833  }
834  }
835 
836  dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
837  $resql = $this->db->query($sql);
838  if ($resql) {
839  unset($this->country_code);
840  unset($this->country);
841  unset($this->state_code);
842  unset($this->state);
843 
844  $nbrowsaffected += $this->db->affected_rows($resql);
845 
846  $action = 'update';
847 
848  // Actions on extra fields
849  if (!$error) {
850  $result = $this->insertExtraFields();
851  if ($result < 0) {
852  $error++;
853  }
854  }
855 
856  // Update password
857  if (!$error && $this->pass) {
858  dol_syslog(get_class($this)."::update update password");
859  if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) {
860  $isencrypted = !getDolGlobalString('DATABASE_PWD_ENCRYPTED') ? 0 : 1;
861 
862  // If password to set differs from the one found into database
863  $result = $this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
864  if (!$nbrowsaffected) {
865  $nbrowsaffected++;
866  }
867  }
868  }
869 
870  // Remove links to user and replace with new one
871  if (!$error) {
872  dol_syslog(get_class($this)."::update update link to user");
873  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
874  dol_syslog(get_class($this)."::update", LOG_DEBUG);
875  $resql = $this->db->query($sql);
876  if (!$resql) {
877  $this->error = $this->db->error();
878  $this->db->rollback();
879  return -5;
880  }
881  // If there is a user linked to this member
882  if ($this->user_id > 0) {
883  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id)." WHERE rowid = ".((int) $this->user_id);
884  dol_syslog(get_class($this)."::update", LOG_DEBUG);
885  $resql = $this->db->query($sql);
886  if (!$resql) {
887  $this->error = $this->db->error();
888  $this->db->rollback();
889  return -5;
890  }
891  }
892  }
893 
894  if (!$error && $nbrowsaffected) { // If something has change in main data
895  // Update information on linked user if it is an update
896  if (!$error && $this->user_id > 0 && !$nosyncuser) {
897  require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
898 
899  dol_syslog(get_class($this)."::update update linked user");
900 
901  $luser = new User($this->db);
902  $result = $luser->fetch($this->user_id);
903 
904  if ($result >= 0) {
905  //var_dump($this->user_login);exit;
906  //var_dump($this->login);exit;
907 
908  // 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.
909  if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
910  $luser->login = $this->login;
911  }
912 
913  $luser->ref = $this->ref;
914  $luser->civility_id = $this->civility_id;
915  $luser->firstname = $this->firstname;
916  $luser->lastname = $this->lastname;
917  $luser->gender = $this->gender;
918  $luser->pass = $this->pass;
919  //$luser->socid=$this->fk_soc; // We do not enable this. This may transform a user into an external user.
920 
921  $luser->birth = $this->birth;
922 
923  $luser->address = $this->address;
924  $luser->zip = $this->zip;
925  $luser->town = $this->town;
926  $luser->country_id = $this->country_id;
927  $luser->state_id = $this->state_id;
928 
929  $luser->email = $this->email;
930  $luser->socialnetworks = $this->socialnetworks;
931  $luser->office_phone = $this->phone;
932  $luser->user_mobile = $this->phone_mobile;
933 
934  $luser->lang = $this->default_lang;
935 
936  $luser->fk_member = $this->id;
937 
938  $result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
939  if ($result < 0) {
940  $this->error = $luser->error;
941  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
942  $error++;
943  }
944  } else {
945  $this->error = $luser->error;
946  $error++;
947  }
948  }
949 
950  // Update information on linked thirdparty if it is an update
951  if (!$error && $this->fk_soc > 0 && !$nosyncthirdparty) {
952  require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
953 
954  dol_syslog(get_class($this)."::update update linked thirdparty");
955 
956  // This member is linked with a thirdparty, so we also update thirdparty information
957  // if this is an update.
958  $lthirdparty = new Societe($this->db);
959  $result = $lthirdparty->fetch($this->fk_soc);
960 
961  if ($result > 0) {
962  $lthirdparty->address = $this->address;
963  $lthirdparty->zip = $this->zip;
964  $lthirdparty->town = $this->town;
965  $lthirdparty->email = $this->email;
966  $lthirdparty->socialnetworks = $this->socialnetworks;
967  $lthirdparty->phone = $this->phone;
968  $lthirdparty->state_id = $this->state_id;
969  $lthirdparty->country_id = $this->country_id;
970  //$lthirdparty->phone_mobile=$this->phone_mobile;
971  $lthirdparty->default_lang = $this->default_lang;
972 
973  $result = $lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
974 
975  if ($result < 0) {
976  $this->error = $lthirdparty->error;
977  $this->errors = $lthirdparty->errors;
978  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
979  $error++;
980  }
981  } elseif ($result < 0) {
982  $this->error = $lthirdparty->error;
983  $error++;
984  }
985  }
986  }
987 
988  if (!$error && !$notrigger) {
989  // Call trigger
990  $result = $this->call_trigger('MEMBER_MODIFY', $user);
991  if ($result < 0) {
992  $error++;
993  }
994  // End call triggers
995  }
996 
997  if (!$error) {
998  $this->db->commit();
999  return $nbrowsaffected;
1000  } else {
1001  $this->db->rollback();
1002  return -1;
1003  }
1004  } else {
1005  $this->db->rollback();
1006  $this->error = $this->db->lasterror();
1007  return -2;
1008  }
1009  }
1010 
1011 
1012  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1020  public function update_end_date($user)
1021  {
1022  // phpcs:enable
1023  $this->db->begin();
1024 
1025  // Search for last subscription id and end date
1026  $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
1027  $sql .= " FROM ".MAIN_DB_PREFIX."subscription";
1028  $sql .= " WHERE fk_adherent = ".((int) $this->id);
1029  $sql .= " ORDER by dateadh DESC"; // Sort by start subscription date
1030 
1031  dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1032  $resql = $this->db->query($sql);
1033  if ($resql) {
1034  $obj = $this->db->fetch_object($resql);
1035  $dateop = $this->db->jdate($obj->dateop);
1036  $datedeb = $this->db->jdate($obj->datedeb);
1037  $datefin = $this->db->jdate($obj->datefin);
1038 
1039  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1040  $sql .= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
1041  $sql .= " WHERE rowid = ".((int) $this->id);
1042 
1043  dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1044  $resql = $this->db->query($sql);
1045  if ($resql) {
1046  $this->last_subscription_date = $dateop;
1047  $this->last_subscription_date_start = $datedeb;
1048  $this->last_subscription_date_end = $datefin;
1049  $this->datefin = $datefin;
1050  $this->db->commit();
1051  return 1;
1052  } else {
1053  $this->db->rollback();
1054  return -1;
1055  }
1056  } else {
1057  $this->error = $this->db->lasterror();
1058  $this->db->rollback();
1059  return -1;
1060  }
1061  }
1062 
1070  public function delete($user, $notrigger = 0)
1071  {
1072  $result = 0;
1073  $error = 0;
1074  $errorflag = 0;
1075 
1076  // Check parameters
1077  $rowid = $this->id;
1078 
1079  $this->db->begin();
1080 
1081  if (!$error && !$notrigger) {
1082  // Call trigger
1083  $result = $this->call_trigger('MEMBER_DELETE', $user);
1084  if ($result < 0) {
1085  $error++;
1086  }
1087  // End call triggers
1088  }
1089 
1090  // Remove category
1091  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".((int) $rowid);
1092  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1093  $resql = $this->db->query($sql);
1094  if (!$resql) {
1095  $error++;
1096  $this->error .= $this->db->lasterror();
1097  $errorflag = -1;
1098  }
1099 
1100  // Remove subscription
1101  if (!$error) {
1102  $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".((int) $rowid);
1103  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1104  $resql = $this->db->query($sql);
1105  if (!$resql) {
1106  $error++;
1107  $this->error .= $this->db->lasterror();
1108  $errorflag = -2;
1109  }
1110  }
1111 
1112  // Remove linked user
1113  if (!$error) {
1114  $ret = $this->setUserId(0);
1115  if ($ret < 0) {
1116  $error++;
1117  $this->error .= $this->db->lasterror();
1118  $errorflag = -3;
1119  }
1120  }
1121 
1122  // Removed extrafields
1123  if (!$error) {
1124  $result = $this->deleteExtraFields();
1125  if ($result < 0) {
1126  $error++;
1127  $errorflag = -4;
1128  dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
1129  }
1130  }
1131 
1132  // Remove adherent
1133  if (!$error) {
1134  $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".((int) $rowid);
1135  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1136  $resql = $this->db->query($sql);
1137  if (!$resql) {
1138  $error++;
1139  $this->error .= $this->db->lasterror();
1140  $errorflag = -5;
1141  }
1142  }
1143 
1144  if (!$error) {
1145  $this->db->commit();
1146  return 1;
1147  } else {
1148  $this->db->rollback();
1149  return $errorflag;
1150  }
1151  }
1152 
1153 
1164  public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
1165  {
1166  global $conf, $langs;
1167 
1168  $error = 0;
1169 
1170  dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." isencrypted=".$isencrypted);
1171 
1172  // If new password not provided, we generate one
1173  if (!$password) {
1174  require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
1175  $password = getRandomPassword(false);
1176  }
1177 
1178  // Crypt password
1179  $password_crypted = dol_hash($password);
1180 
1181  $password_indatabase = '';
1182  if (!$isencrypted) {
1183  $password_indatabase = $password;
1184  }
1185 
1186  $this->db->begin();
1187 
1188  // Mise a jour
1189  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
1190  $sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
1191  if ($isencrypted) {
1192  $sql .= ", pass = null";
1193  } else {
1194  $sql .= ", pass = '".$this->db->escape($password_indatabase)."'";
1195  }
1196  $sql .= " WHERE rowid = ".((int) $this->id);
1197 
1198  //dol_syslog("Adherent::Password sql=hidden");
1199  dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1200  $result = $this->db->query($sql);
1201  if ($result) {
1202  $nbaffectedrows = $this->db->affected_rows($result);
1203 
1204  if ($nbaffectedrows) {
1205  $this->pass = $password;
1206  $this->pass_indatabase = $password_indatabase;
1207  $this->pass_indatabase_crypted = $password_crypted;
1208 
1209  if ($this->user_id && !$nosyncuser) {
1210  require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1211 
1212  // This member is linked with a user, so we also update users information
1213  // if this is an update.
1214  $luser = new User($this->db);
1215  $result = $luser->fetch($this->user_id);
1216 
1217  if ($result >= 0) {
1218  $result = $luser->setPassword($user, $this->pass, 0, 0, 1);
1219  if (is_int($result) && $result < 0) {
1220  $this->error = $luser->error;
1221  dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR);
1222  $error++;
1223  }
1224  } else {
1225  $this->error = $luser->error;
1226  $error++;
1227  }
1228  }
1229 
1230  if (!$error && !$notrigger) {
1231  // Call trigger
1232  $result = $this->call_trigger('MEMBER_NEW_PASSWORD', $user);
1233  if ($result < 0) {
1234  $error++;
1235  $this->db->rollback();
1236  return -1;
1237  }
1238  // End call triggers
1239  }
1240 
1241  $this->db->commit();
1242  return $this->pass;
1243  } else {
1244  $this->db->rollback();
1245  return 0;
1246  }
1247  } else {
1248  $this->db->rollback();
1249  dol_print_error($this->db);
1250  return -1;
1251  }
1252  }
1253 
1254 
1261  public function setUserId($userid)
1262  {
1263  global $conf, $langs;
1264 
1265  $this->db->begin();
1266 
1267  // If user is linked to this member, remove old link to this member
1268  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
1269  dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1270  $resql = $this->db->query($sql);
1271  if (!$resql) {
1272  $this->error = $this->db->error();
1273  $this->db->rollback();
1274  return -1;
1275  }
1276 
1277  // Set link to user
1278  if ($userid > 0) {
1279  $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id);
1280  $sql .= " WHERE rowid = ".((int) $userid);
1281  dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1282  $resql = $this->db->query($sql);
1283  if (!$resql) {
1284  $this->error = $this->db->error();
1285  $this->db->rollback();
1286  return -2;
1287  }
1288  }
1289 
1290  $this->db->commit();
1291 
1292  return 1;
1293  }
1294 
1295 
1302  public function setThirdPartyId($thirdpartyid)
1303  {
1304  global $conf, $langs;
1305 
1306  $this->db->begin();
1307 
1308  // Remove link to third party onto any other members
1309  if ($thirdpartyid > 0) {
1310  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
1311  $sql .= " WHERE fk_soc = ".((int) $thirdpartyid);
1312  $sql .= " AND entity = ".$conf->entity;
1313  dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1314  $resql = $this->db->query($sql);
1315  }
1316 
1317  // Add link to third party for current member
1318  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid > 0 ? (int) $thirdpartyid : 'null');
1319  $sql .= " WHERE rowid = ".((int) $this->id);
1320 
1321  dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1322  $resql = $this->db->query($sql);
1323  if ($resql) {
1324  $this->db->commit();
1325  return 1;
1326  } else {
1327  $this->error = $this->db->error();
1328  $this->db->rollback();
1329  return -1;
1330  }
1331  }
1332 
1333 
1334  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1341  public function fetch_login($login)
1342  {
1343  // phpcs:enable
1344  global $conf;
1345 
1346  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1347  $sql .= " WHERE login='".$this->db->escape($login)."'";
1348  $sql .= " AND entity = ".$conf->entity;
1349 
1350  $resql = $this->db->query($sql);
1351  if ($resql) {
1352  if ($this->db->num_rows($resql)) {
1353  $obj = $this->db->fetch_object($resql);
1354  $this->fetch($obj->rowid);
1355  }
1356  } else {
1357  dol_print_error($this->db);
1358  }
1359  }
1360 
1361  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1369  public function fetch_name($firstname, $lastname)
1370  {
1371  // phpcs:enable
1372  global $conf;
1373 
1374  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1375  $sql .= " WHERE firstname='".$this->db->escape($firstname)."'";
1376  $sql .= " AND lastname='".$this->db->escape($lastname)."'";
1377  $sql .= " AND entity = ".$conf->entity;
1378 
1379  $resql = $this->db->query($sql);
1380  if ($resql) {
1381  if ($this->db->num_rows($resql)) {
1382  $obj = $this->db->fetch_object($resql);
1383  $this->fetch($obj->rowid);
1384  }
1385  } else {
1386  dol_print_error($this->db);
1387  }
1388  }
1389 
1401  public function fetch($rowid, $ref = '', $fk_soc = 0, $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
1402  {
1403  global $langs;
1404 
1405  $sql = "SELECT d.rowid, d.ref, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname,";
1406  $sql .= " d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1407  $sql .= " d.note_public,";
1408  $sql .= " d.email, d.url, d.socialnetworks, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1409  $sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1410  $sql .= " d.datec as datec,";
1411  $sql .= " d.tms as datem,";
1412  $sql .= " d.datefin as datefin, d.default_lang,";
1413  $sql .= " d.birth as birthday,";
1414  $sql .= " d.datevalid as datev,";
1415  $sql .= " d.country,";
1416  $sql .= " d.state_id,";
1417  $sql .= " d.model_pdf,";
1418  $sql .= " c.rowid as country_id, c.code as country_code, c.label as country,";
1419  $sql .= " dep.nom as state, dep.code_departement as state_code,";
1420  $sql .= " t.libelle as type, t.subscription as subscription,";
1421  $sql .= " u.rowid as user_id, u.login as user_login";
1422  $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
1423  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
1424  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
1425  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
1426  $sql .= " WHERE d.fk_adherent_type = t.rowid";
1427  if ($rowid) {
1428  $sql .= " AND d.rowid=".((int) $rowid);
1429  } elseif ($ref || $fk_soc) {
1430  $sql .= " AND d.entity IN (".getEntity('adherent').")";
1431  if ($ref) {
1432  $sql .= " AND d.ref='".$this->db->escape($ref)."'";
1433  } elseif ($fk_soc > 0) {
1434  $sql .= " AND d.fk_soc=".((int) $fk_soc);
1435  }
1436  } elseif ($ref_ext) {
1437  $sql .= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
1438  }
1439 
1440  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1441  $resql = $this->db->query($sql);
1442  if ($resql) {
1443  if ($this->db->num_rows($resql)) {
1444  $obj = $this->db->fetch_object($resql);
1445 
1446  $this->entity = $obj->entity;
1447  $this->id = $obj->rowid;
1448  $this->ref = $obj->ref;
1449  $this->ref_ext = $obj->ref_ext;
1450 
1451  $this->civility_id = $obj->civility_code; // Bad. Kept for backward compatibility
1452  $this->civility_code = $obj->civility_code;
1453  $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : '';
1454 
1455  $this->firstname = $obj->firstname;
1456  $this->lastname = $obj->lastname;
1457  $this->gender = $obj->gender;
1458  $this->login = $obj->login;
1459  $this->societe = $obj->company;
1460  $this->company = $obj->company;
1461  $this->socid = $obj->fk_soc;
1462  $this->fk_soc = $obj->fk_soc; // For backward compatibility
1463  $this->address = $obj->address;
1464  $this->zip = $obj->zip;
1465  $this->town = $obj->town;
1466 
1467  $this->pass = $obj->pass;
1468  $this->pass_indatabase = $obj->pass;
1469  $this->pass_indatabase_crypted = $obj->pass_crypted;
1470 
1471  $this->state_id = $obj->state_id;
1472  $this->state_code = $obj->state_id ? $obj->state_code : '';
1473  $this->state = $obj->state_id ? $obj->state : '';
1474 
1475  $this->country_id = $obj->country_id;
1476  $this->country_code = $obj->country_code;
1477  if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) {
1478  $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
1479  } else {
1480  $this->country = $obj->country;
1481  }
1482 
1483  $this->phone = $obj->phone;
1484  $this->phone_perso = $obj->phone_perso;
1485  $this->phone_mobile = $obj->phone_mobile;
1486  $this->email = $obj->email;
1487  $this->url = $obj->url;
1488 
1489  $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1490 
1491  $this->photo = $obj->photo;
1492  $this->statut = $obj->statut;
1493  $this->status = $obj->statut;
1494  $this->public = $obj->public;
1495 
1496  $this->datec = $this->db->jdate($obj->datec);
1497  $this->date_creation = $this->db->jdate($obj->datec);
1498  $this->datem = $this->db->jdate($obj->datem);
1499  $this->date_modification = $this->db->jdate($obj->datem);
1500  $this->datefin = $this->db->jdate($obj->datefin);
1501  $this->datevalid = $this->db->jdate($obj->datev);
1502  $this->date_validation = $this->db->jdate($obj->datev);
1503  $this->birth = $this->db->jdate($obj->birthday);
1504 
1505  $this->default_lang = $obj->default_lang;
1506 
1507  $this->note_private = $obj->note_private;
1508  $this->note_public = $obj->note_public;
1509  $this->morphy = $obj->morphy;
1510 
1511  $this->typeid = $obj->fk_adherent_type;
1512  $this->type = $obj->type;
1513  $this->need_subscription = $obj->subscription;
1514 
1515  $this->user_id = $obj->user_id;
1516  $this->user_login = $obj->user_login;
1517 
1518  $this->model_pdf = $obj->model_pdf;
1519 
1520  // Retrieve all extrafield
1521  // fetch optionals attributes and labels
1522  if ($fetch_optionals) {
1523  $this->fetch_optionals();
1524  }
1525 
1526  // Load other properties
1527  if ($fetch_subscriptions) {
1528  $result = $this->fetch_subscriptions();
1529  }
1530 
1531  return $this->id;
1532  } else {
1533  return 0;
1534  }
1535  } else {
1536  $this->error = $this->db->lasterror();
1537  return -1;
1538  }
1539  }
1540 
1541 
1542  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1551  public function fetch_subscriptions()
1552  {
1553  // phpcs:enable
1554  global $langs;
1555 
1556  require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1557 
1558  $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
1559  $sql .= " c.tms as datem,";
1560  $sql .= " c.datec as datec,";
1561  $sql .= " c.dateadh as dateh,";
1562  $sql .= " c.datef as datef";
1563  $sql .= " FROM ".MAIN_DB_PREFIX."subscription as c";
1564  $sql .= " WHERE c.fk_adherent = ".((int) $this->id);
1565  $sql .= " ORDER BY c.dateadh";
1566  dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
1567 
1568  $resql = $this->db->query($sql);
1569  if ($resql) {
1570  $this->subscriptions = array();
1571 
1572  $i = 0;
1573  while ($obj = $this->db->fetch_object($resql)) {
1574  if ($i == 0) {
1575  $this->first_subscription_date = $this->db->jdate($obj->datec);
1576  $this->first_subscription_date_start = $this->db->jdate($obj->dateh);
1577  $this->first_subscription_date_end = $this->db->jdate($obj->datef);
1578  $this->first_subscription_amount = $obj->subscription;
1579  }
1580  $this->last_subscription_date = $this->db->jdate($obj->datec);
1581  $this->last_subscription_date_start = $this->db->jdate($obj->dateh);
1582  $this->last_subscription_date_end = $this->db->jdate($obj->datef);
1583  $this->last_subscription_amount = $obj->subscription;
1584 
1585  $subscription = new Subscription($this->db);
1586  $subscription->id = $obj->rowid;
1587  $subscription->fk_adherent = $obj->fk_adherent;
1588  $subscription->fk_type = $obj->fk_type;
1589  $subscription->amount = $obj->subscription;
1590  $subscription->note = $obj->note_public;
1591  $subscription->note_public = $obj->note_public;
1592  $subscription->fk_bank = $obj->fk_bank;
1593  $subscription->datem = $this->db->jdate($obj->datem);
1594  $subscription->datec = $this->db->jdate($obj->datec);
1595  $subscription->dateh = $this->db->jdate($obj->dateh);
1596  $subscription->datef = $this->db->jdate($obj->datef);
1597 
1598  $this->subscriptions[] = $subscription;
1599 
1600  $i++;
1601  }
1602  return 1;
1603  } else {
1604  $this->error = $this->db->error().' sql='.$sql;
1605  return -1;
1606  }
1607  }
1608 
1609 
1616  public function fetchPartnerships($mode)
1617  {
1618  global $langs;
1619 
1620  require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php';
1621 
1622 
1623  $this->partnerships[] = array();
1624 
1625  return 1;
1626  }
1627 
1628 
1644  public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
1645  {
1646  global $conf, $langs, $user;
1647 
1648  require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1649 
1650  $error = 0;
1651 
1652  // Clean parameters
1653  if (!$amount) {
1654  $amount = 0;
1655  }
1656 
1657  $this->db->begin();
1658 
1659  if ($datesubend) {
1660  $datefin = $datesubend;
1661  } else {
1662  // If no end date, end date = date + 1 year - 1 day
1663  $datefin = dol_time_plus_duree($date, 1, 'y');
1664  $datefin = dol_time_plus_duree($datefin, -1, 'd');
1665  }
1666 
1667  // Create subscription
1668  $subscription = new Subscription($this->db);
1669  $subscription->fk_adherent = $this->id;
1670  $subscription->dateh = $date; // Date of new subscription
1671  $subscription->datef = $datefin; // End data of new subscription
1672  $subscription->amount = $amount;
1673  $subscription->note = $label; // deprecated
1674  $subscription->note_public = $label;
1675  $subscription->fk_type = $fk_type;
1676 
1677  $rowid = $subscription->create($user);
1678  if ($rowid > 0) {
1679  // Update denormalized subscription end date (read database subscription to find values)
1680  // This will also update this->datefin
1681  $result = $this->update_end_date($user);
1682  if ($result > 0) {
1683  // Change properties of object (used by triggers)
1684  $this->last_subscription_date = dol_now();
1685  $this->last_subscription_date_start = $date;
1686  $this->last_subscription_date_end = $datefin;
1687  $this->last_subscription_amount = $amount;
1688  }
1689 
1690  if (!$error) {
1691  $this->db->commit();
1692  return $rowid;
1693  } else {
1694  $this->db->rollback();
1695  return -2;
1696  }
1697  } else {
1698  $this->setErrorsFromObject($subscription);
1699  $this->db->rollback();
1700  return -1;
1701  }
1702  }
1703 
1704 
1724  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 = '')
1725  {
1726  global $conf, $langs, $user, $mysoc;
1727 
1728  $error = 0;
1729 
1730  $this->invoice = null; // This will contains invoice if an invoice is created
1731 
1732  dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".
1733  $paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
1734 
1735  // Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
1736  if ($option == 'bankdirect' && $accountid) {
1737  require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1738 
1739  $acct = new Account($this->db);
1740  $result = $acct->fetch($accountid);
1741 
1742  $dateop = $paymentdate;
1743 
1744  $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, '', $user, $emetteur_nom, $emetteur_banque);
1745  if ($insertid > 0) {
1746  $inserturlid = $acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
1747  if ($inserturlid > 0) {
1748  // Update table subscription
1749  $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".((int) $insertid);
1750  $sql .= " WHERE rowid=".((int) $subscriptionid);
1751 
1752  dol_syslog("subscription::subscription", LOG_DEBUG);
1753  $resql = $this->db->query($sql);
1754  if (!$resql) {
1755  $error++;
1756  $this->error = $this->db->lasterror();
1757  $this->errors[] = $this->error;
1758  }
1759  } else {
1760  $error++;
1761  $this->setErrorsFromObject($acct);
1762  }
1763  } else {
1764  $error++;
1765  $this->setErrorsFromObject($acct);
1766  }
1767  }
1768 
1769  // If option chosen, we create invoice
1770  if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
1771  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1772  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
1773 
1774  $invoice = new Facture($this->db);
1775  $customer = new Societe($this->db);
1776 
1777  if (!$error) {
1778  if (!($this->fk_soc > 0)) { // If not yet linked to a company
1779  if ($autocreatethirdparty) {
1780  // Create a linked thirdparty to member
1781  $companyalias = '';
1782  $fullname = $this->getFullName($langs);
1783 
1784  if ($this->morphy == 'mor') {
1785  $companyname = $this->company;
1786  if (!empty($fullname)) {
1787  $companyalias = $fullname;
1788  }
1789  } else {
1790  $companyname = $fullname;
1791  if (!empty($this->company)) {
1792  $companyalias = $this->company;
1793  }
1794  }
1795 
1796  $result = $customer->create_from_member($this, $companyname, $companyalias);
1797  if ($result < 0) {
1798  $this->error = $customer->error;
1799  $this->errors = $customer->errors;
1800  $error++;
1801  } else {
1802  $this->fk_soc = $result;
1803  }
1804  } else {
1805  $langs->load("errors");
1806  $this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1807  $this->errors[] = $this->error;
1808  $error++;
1809  }
1810  }
1811  }
1812  if (!$error) {
1813  $result = $customer->fetch($this->fk_soc);
1814  if ($result <= 0) {
1815  $this->error = $customer->error;
1816  $this->errors = $customer->errors;
1817  $error++;
1818  }
1819  }
1820 
1821  if (!$error) {
1822  // Create draft invoice
1823  $invoice->type = Facture::TYPE_STANDARD;
1824  $invoice->cond_reglement_id = $customer->cond_reglement_id;
1825  if (empty($invoice->cond_reglement_id)) {
1826  $paymenttermstatic = new PaymentTerm($this->db);
1827  $invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
1828  if (empty($invoice->cond_reglement_id)) {
1829  $error++;
1830  $this->error = 'ErrorNoPaymentTermRECEPFound';
1831  $this->errors[] = $this->error;
1832  }
1833  }
1834  $invoice->socid = $this->fk_soc;
1835  //$invoice->date = $datesubscription;
1836  $invoice->date = dol_now();
1837 
1838  // Possibility to add external linked objects with hooks
1839  $invoice->linked_objects['subscription'] = $subscriptionid;
1840  if (GETPOSTISARRAY('other_linked_objects')) {
1841  $invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int'));
1842  }
1843 
1844  $result = $invoice->create($user);
1845  if ($result <= 0) {
1846  $this->error = $invoice->error;
1847  $this->errors = $invoice->errors;
1848  $error++;
1849  } else {
1850  $this->invoice = $invoice;
1851  }
1852  }
1853 
1854  if (!$error) {
1855  // Add line to draft invoice
1856  $idprodsubscription = 0;
1857  if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
1858  $idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
1859  }
1860 
1861  $vattouse = 0;
1862  if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
1863  $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
1864  }
1865  //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1866  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1867  $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, '', 'TTC', $amount, 1);
1868  if ($result <= 0) {
1869  $this->error = $invoice->error;
1870  $this->errors = $invoice->errors;
1871  $error++;
1872  }
1873  }
1874 
1875  if (!$error) {
1876  // Validate invoice
1877  $result = $invoice->validate($user);
1878  if ($result <= 0) {
1879  $this->error = $invoice->error;
1880  $this->errors = $invoice->errors;
1881  $error++;
1882  }
1883  }
1884 
1885  if (!$error) {
1886  // TODO Link invoice with subscription ?
1887  }
1888 
1889  // Add payment onto invoice
1890  if (!$error && $option == 'bankviainvoice' && $accountid) {
1891  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1892  require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1893  require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
1894 
1895  $amounts = array();
1896  $amounts[$invoice->id] = (float) price2num($amount);
1897 
1898  $paiement = new Paiement($this->db);
1899  $paiement->datepaye = $paymentdate;
1900  $paiement->amounts = $amounts;
1901  $paiement->paiementcode = $operation;
1902  $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
1903  $paiement->num_payment = $num_chq;
1904  $paiement->note_public = $label;
1905  $paiement->ext_payment_id = $ext_payment_id;
1906  $paiement->ext_payment_site = $ext_payment_site;
1907 
1908  if (!$error) {
1909  // Create payment line for invoice
1910  $paiement_id = $paiement->create($user);
1911  if (!($paiement_id > 0)) {
1912  $this->error = $paiement->error;
1913  $this->errors = $paiement->errors;
1914  $error++;
1915  }
1916  }
1917 
1918  if (!$error) {
1919  // Add transaction into bank account
1920  $bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
1921  if (!($bank_line_id > 0)) {
1922  $this->error = $paiement->error;
1923  $this->errors = $paiement->errors;
1924  $error++;
1925  }
1926  }
1927 
1928  if (!$error && !empty($bank_line_id)) {
1929  // Update fk_bank into subscription table
1930  $sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.((int) $bank_line_id);
1931  $sql .= ' WHERE rowid='.((int) $subscriptionid);
1932 
1933  $result = $this->db->query($sql);
1934  if (!$result) {
1935  $error++;
1936  }
1937  }
1938 
1939  if (!$error) {
1940  // Set invoice as paid
1941  $invoice->setPaid($user);
1942  }
1943  }
1944 
1945  if (!$error) {
1946  // Define output language
1947  $outputlangs = $langs;
1948  $newlang = '';
1949  $lang_id = GETPOST('lang_id');
1950  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
1951  $newlang = $lang_id;
1952  }
1953  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1954  $newlang = $customer->default_lang;
1955  }
1956  if (!empty($newlang)) {
1957  $outputlangs = new Translate("", $conf);
1958  $outputlangs->setDefaultLang($newlang);
1959  }
1960  // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
1961  //if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
1962 
1963  $invoice->generateDocument($invoice->model_pdf, $outputlangs);
1964  }
1965  }
1966 
1967  if ($error) {
1968  return -1;
1969  } else {
1970  return 1;
1971  }
1972  }
1973 
1974 
1981  public function validate($user)
1982  {
1983  global $langs, $conf;
1984 
1985  $error = 0;
1986  $now = dol_now();
1987 
1988  // Check parameters
1989  if ($this->statut == self::STATUS_VALIDATED) {
1990  dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
1991  return 0;
1992  }
1993 
1994  $this->db->begin();
1995 
1996  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1997  $sql .= " statut = ".self::STATUS_VALIDATED;
1998  $sql .= ", datevalid = '".$this->db->idate($now)."'";
1999  $sql .= ", fk_user_valid = ".((int) $user->id);
2000  $sql .= " WHERE rowid = ".((int) $this->id);
2001 
2002  dol_syslog(get_class($this)."::validate", LOG_DEBUG);
2003  $result = $this->db->query($sql);
2004  if ($result) {
2005  $this->statut = self::STATUS_VALIDATED;
2006 
2007  // Call trigger
2008  $result = $this->call_trigger('MEMBER_VALIDATE', $user);
2009  if ($result < 0) {
2010  $error++;
2011  $this->db->rollback();
2012  return -1;
2013  }
2014  // End call triggers
2015 
2016  $this->datevalid = $now;
2017 
2018  $this->db->commit();
2019  return 1;
2020  } else {
2021  $this->error = $this->db->error();
2022  $this->db->rollback();
2023  return -1;
2024  }
2025  }
2026 
2027 
2034  public function resiliate($user)
2035  {
2036  global $langs, $conf;
2037 
2038  $error = 0;
2039 
2040  // Check parameters
2041  if ($this->statut == self::STATUS_RESILIATED) {
2042  dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2043  return 0;
2044  }
2045 
2046  $this->db->begin();
2047 
2048  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2049  $sql .= " statut = ".self::STATUS_RESILIATED;
2050  $sql .= ", fk_user_valid=".$user->id;
2051  $sql .= " WHERE rowid = ".((int) $this->id);
2052 
2053  $result = $this->db->query($sql);
2054  if ($result) {
2055  $this->statut = self::STATUS_RESILIATED;
2056 
2057  // Call trigger
2058  $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2059  if ($result < 0) {
2060  $error++;
2061  $this->db->rollback();
2062  return -1;
2063  }
2064  // End call triggers
2065 
2066  $this->db->commit();
2067  return 1;
2068  } else {
2069  $this->error = $this->db->error();
2070  $this->db->rollback();
2071  return -1;
2072  }
2073  }
2074 
2084  public function exclude($user)
2085  {
2086  $error = 0;
2087 
2088  // Check parameters
2089  if ($this->statut == self::STATUS_EXCLUDED) {
2090  dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2091  return 0;
2092  }
2093 
2094  $this->db->begin();
2095 
2096  $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2097  $sql .= " statut = ".self::STATUS_EXCLUDED;
2098  $sql .= ", fk_user_valid=".$user->id;
2099  $sql .= " WHERE rowid = ".((int) $this->id);
2100 
2101  $result = $this->db->query($sql);
2102  if ($result) {
2103  $this->statut = self::STATUS_EXCLUDED;
2104 
2105  // Call trigger
2106  $result = $this->call_trigger('MEMBER_EXCLUDE', $user);
2107  if ($result < 0) {
2108  $error++;
2109  $this->db->rollback();
2110  return -1;
2111  }
2112  // End call triggers
2113 
2114  $this->db->commit();
2115  return 1;
2116  } else {
2117  $this->error = $this->db->error();
2118  $this->db->rollback();
2119  return -1;
2120  }
2121  }
2122 
2123  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2129  public function add_to_abo()
2130  {
2131  // phpcs:enable
2132  global $langs;
2133 
2134  include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2135  $mailmanspip = new MailmanSpip($this->db);
2136 
2137  $err = 0;
2138 
2139  // mailman
2140  if (getDolGlobalString('ADHERENT_USE_MAILMAN') && isModEnabled('mailmanspip')) {
2141  $result = $mailmanspip->add_to_mailman($this);
2142 
2143  if ($result < 0) {
2144  if (!empty($mailmanspip->error)) {
2145  $this->errors[] = $mailmanspip->error;
2146  }
2147  $err += 1;
2148  }
2149  foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) {
2150  $langs->load("errors");
2151  $this->errors[] = $langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
2152  }
2153  foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) {
2154  $langs->load("mailmanspip");
2155  $this->mesgs[] = $langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
2156  }
2157  }
2158 
2159  // spip
2160  if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2161  $result = $mailmanspip->add_to_spip($this);
2162  if ($result < 0) {
2163  $this->errors[] = $mailmanspip->error;
2164  $err += 1;
2165  }
2166  }
2167  if ($err) {
2168  return -$err;
2169  } else {
2170  return 1;
2171  }
2172  }
2173 
2174 
2175  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2181  public function del_to_abo()
2182  {
2183  // phpcs:enable
2184  global $conf, $langs;
2185 
2186  include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2187  $mailmanspip = new MailmanSpip($this->db);
2188 
2189  $err = 0;
2190 
2191  // mailman
2192  if (getDolGlobalString('ADHERENT_USE_MAILMAN')) {
2193  $result = $mailmanspip->del_to_mailman($this);
2194  if ($result < 0) {
2195  if (!empty($mailmanspip->error)) {
2196  $this->errors[] = $mailmanspip->error;
2197  }
2198  $err += 1;
2199  }
2200 
2201  foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) {
2202  $langs->load("errors");
2203  $this->errors[] = $langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
2204  }
2205  foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) {
2206  $langs->load("mailmanspip");
2207  $this->mesgs[] = $langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
2208  }
2209  }
2210 
2211  if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2212  $result = $mailmanspip->del_to_spip($this);
2213  if ($result < 0) {
2214  $this->errors[] = $mailmanspip->error;
2215  $err += 1;
2216  }
2217  }
2218  if ($err) {
2219  // error
2220  return -$err;
2221  } else {
2222  return 1;
2223  }
2224  }
2225 
2226 
2232  public function getCivilityLabel()
2233  {
2234  global $langs;
2235  $langs->load("dict");
2236 
2237  $code = (empty($this->civility_id) ? '' : $this->civility_id);
2238  if (empty($code)) {
2239  return '';
2240  }
2241  return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
2242  }
2243 
2250  public function getTooltipContentArray($params)
2251  {
2252  global $langs;
2253 
2254  $langs->loadLangs(['members', 'companies']);
2255  $nofetch = !empty($params['nofetch']);
2256 
2257  $datas = array();
2258 
2259  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2260  $langs->load("users");
2261  return ['optimize' => $langs->trans("ShowUser")];
2262  }
2263  if (!empty($this->photo)) {
2264  $photo = '<div class="photointooltip floatright">';
2265  $photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1);
2266  $photo .= '</div>';
2267  $datas['photo'] = $photo;
2268  }
2269 
2270  $datas['divopen'] = '<div class="centpercent">';
2271  $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Member").'</u> '.$this->getLibStatut(4);
2272  if (!empty($this->morphy)) {
2273  $datas['picto'] .= '&nbsp;' . $this->getmorphylib('', 1);
2274  }
2275  if (!empty($this->ref)) {
2276  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
2277  }
2278  if (!empty($this->login)) {
2279  $datas['login'] = '<br><b>'.$langs->trans('Login').':</b> '.$this->login;
2280  }
2281  if (!empty($this->firstname) || !empty($this->lastname)) {
2282  $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
2283  }
2284  if (!empty($this->company)) {
2285  $datas['company'] = '<br><b>'.$langs->trans('Company').':</b> '.$this->company;
2286  }
2287  if (!empty($this->email)) {
2288  $datas['email'] = '<br><b>'.$langs->trans("EMail").':</b> '.$this->email;
2289  }
2290  $datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs);
2291  // show categories for this record only in ajax to not overload lists
2292  if (isModEnabled('category') && !$nofetch) {
2293  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
2294  $form = new Form($this->db);
2295  $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_MEMBER, 1);
2296  }
2297  $datas['divclose'] = '</div>';
2298 
2299  return $datas;
2300  }
2301 
2315  public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0)
2316  {
2317  global $conf, $langs, $hookmanager;
2318 
2319  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpictoimg) {
2320  $withpictoimg = 0;
2321  }
2322 
2323  $result = '';
2324  $linkstart = '';
2325  $linkend = '';
2326  $classfortooltip = 'classfortooltip';
2327  $dataparams = '';
2328  $params = [
2329  'id' => $this->id,
2330  'objecttype' => $this->element,
2331  'option' => $option,
2332  'nofetch' => 1,
2333  ];
2334  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
2335  $classfortooltip = 'classforajaxtooltip';
2336  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
2337  $label = '';
2338  } else {
2339  $label = implode($this->getTooltipContentArray($params));
2340  }
2341 
2342  $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.((int) $this->id);
2343  if ($option == 'subscription') {
2344  $url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.((int) $this->id);
2345  }
2346 
2347  if ($option != 'nolink') {
2348  // Add param to save lastsearch_values or not
2349  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2350  if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
2351  $add_save_lastsearch_values = 1;
2352  }
2353  if ($add_save_lastsearch_values) {
2354  $url .= '&save_lastsearch_values=1';
2355  }
2356  }
2357 
2358  $linkstart .= '<a href="'.$url.'"';
2359  $linkclose = "";
2360  if (empty($notooltip)) {
2361  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2362  $langs->load("users");
2363  $label = $langs->trans("ShowUser");
2364  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
2365  }
2366  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
2367  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
2368  }
2369 
2370  $linkstart .= $linkclose.'>';
2371  $linkend = '</a>';
2372 
2373  $result .= $linkstart;
2374  if ($withpictoimg) {
2375  $result .= '<div class="inline-block nopadding valignmiddle">';
2376  }
2377  if ($withpictoimg) {
2378  $paddafterimage = '';
2379  if (abs($withpictoimg) == 1 || abs($withpictoimg) == 4) {
2380  $morecss .= ' paddingrightonly';
2381  }
2382  // Only picto
2383  if ($withpictoimg > 0) {
2384  $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1).'</span>';
2385  } else {
2386  // Picto must be a photo
2387  $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'"'.($paddafterimage ? ' '.$paddafterimage : '').'>';
2388  $picto .= Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.(($withpictoimg == -3 || $withpictoimg == -4) ? 'small' : ''), 'mini', 0, 1);
2389  $picto .= '</span>';
2390  }
2391  $result .= $picto;
2392  }
2393  if (($withpictoimg > -2 && $withpictoimg != 2) || $withpictoimg == -4) {
2394  if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2395  $result .= '<span class="nopadding valignmiddle'.((!isset($this->statut) || $this->statut) ? '' : ' strikefordisabled').
2396  ($morecss ? ' usertext'.$morecss : '').'">';
2397  }
2398  if ($mode == 'login') {
2399  $result .= dol_trunc($this->login, $maxlen);
2400  } elseif ($mode == 'ref') {
2401  $result .= $this->ref;
2402  } else {
2403  $result .= $this->getFullName($langs, '', ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2404  }
2405  if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2406  $result .= '</span>';
2407  }
2408  }
2409  if ($withpictoimg) {
2410  $result .= '</div>';
2411  }
2412  $result .= $linkend;
2413 
2414  if ($addlinktonotes) {
2415  if ($this->note_private) {
2416  $notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($this->note_private, 1);
2417  $result .= ' <span class="note inline-block">';
2418  $result .= '<a href="'.DOL_URL_ROOT.'/adherents/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
2419  $result .= img_picto('', 'note');
2420  $result .= '</a>';
2421  $result .= '</span>';
2422  }
2423  }
2424  global $action;
2425  $hookmanager->initHooks(array($this->element . 'dao'));
2426  $parameters = array('id' => $this->id, 'getnomurl' => &$result);
2427  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2428  if ($reshook > 0) {
2429  $result = $hookmanager->resPrint;
2430  } else {
2431  $result .= $hookmanager->resPrint;
2432  }
2433  return $result;
2434  }
2435 
2442  public function getLibStatut($mode = 0)
2443  {
2444  return $this->LibStatut($this->statut, $this->need_subscription, $this->datefin, $mode);
2445  }
2446 
2447  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2457  public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
2458  {
2459  // phpcs:enable
2460  global $langs;
2461  $langs->load("members");
2462 
2463  $statusType = '';
2464  $labelStatus = '';
2465  $labelStatusShort = '';
2466 
2467  if ($status == self::STATUS_DRAFT) {
2468  $statusType = 'status0';
2469  $labelStatus = $langs->trans("MemberStatusDraft");
2470  $labelStatusShort = $langs->trans("MemberStatusDraftShort");
2471  } elseif ($status >= self::STATUS_VALIDATED) {
2472  if ($need_subscription === 0) {
2473  $statusType = 'status4';
2474  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusNoSubscription");
2475  $labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
2476  } elseif (!$date_end_subscription) {
2477  $statusType = 'status1';
2478  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("WaitingSubscription");
2479  $labelStatusShort = $langs->trans("WaitingSubscriptionShort");
2480  } elseif ($date_end_subscription < dol_now()) { // expired
2481  $statusType = 'status8';
2482  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusActiveLate");
2483  $labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
2484  } else {
2485  $statusType = 'status4';
2486  $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusPaid");
2487  $labelStatusShort = $langs->trans("MemberStatusPaidShort");
2488  }
2489  } elseif ($status == self::STATUS_RESILIATED) {
2490  $statusType = 'status6';
2491  $labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
2492  $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
2493  } elseif ($status == self::STATUS_EXCLUDED) {
2494  $statusType = 'status10';
2495  $labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
2496  $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
2497  }
2498 
2499  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
2500  }
2501 
2502 
2508  public function loadStateBoard()
2509  {
2510  global $conf;
2511 
2512  $this->nb = array();
2513 
2514  $sql = "SELECT count(a.rowid) as nb";
2515  $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2516  $sql .= " WHERE a.statut > 0";
2517  $sql .= " AND a.entity IN (".getEntity('adherent').")";
2518 
2519  $resql = $this->db->query($sql);
2520  if ($resql) {
2521  while ($obj = $this->db->fetch_object($resql)) {
2522  $this->nb["members"] = $obj->nb;
2523  }
2524  $this->db->free($resql);
2525  return 1;
2526  } else {
2527  dol_print_error($this->db);
2528  $this->error = $this->db->error();
2529  return -1;
2530  }
2531  }
2532 
2533  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2541  public function load_board($user, $mode)
2542  {
2543  // phpcs:enable
2544  global $conf, $langs;
2545 
2546  if ($user->socid) {
2547  return -1; // protection pour eviter appel par utilisateur externe
2548  }
2549 
2550  $now = dol_now();
2551 
2552  $sql = "SELECT a.rowid, a.datefin, a.statut";
2553  $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2554  $sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
2555  $sql .= " WHERE a.fk_adherent_type = t.rowid";
2556  if ($mode == 'expired') {
2557  $sql .= " AND a.statut = ".self::STATUS_VALIDATED;
2558  $sql .= " AND a.entity IN (".getEntity('adherent').")";
2559  $sql .= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = '1')";
2560  } elseif ($mode == 'shift') {
2561  $sql .= " AND a.statut = ".self::STATUS_DRAFT;
2562  $sql .= " AND a.entity IN (".getEntity('adherent').")";
2563  }
2564 
2565  $resql = $this->db->query($sql);
2566  if ($resql) {
2567  $langs->load("members");
2568 
2569  $warning_delay = 0;
2570  $url = '';
2571  $label = '';
2572  $labelShort = '';
2573 
2574  if ($mode == 'expired') {
2575  $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2576  $label = $langs->trans("MembersWithSubscriptionToReceive");
2577  $labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
2578  $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_VALIDATED.'&amp;filter=outofdate';
2579  } elseif ($mode == 'shift') {
2580  $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2581  $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_DRAFT;
2582  $label = $langs->trans("MembersListToValid");
2583  $labelShort = $langs->trans("ToValidate");
2584  }
2585 
2586  $response = new WorkboardResponse();
2587  $response->warning_delay = $warning_delay;
2588  $response->label = $label;
2589  $response->labelShort = $labelShort;
2590  $response->url = $url;
2591  $response->img = img_object('', "user");
2592 
2593  $adherentstatic = new Adherent($this->db);
2594 
2595  while ($obj = $this->db->fetch_object($resql)) {
2596  $response->nbtodo++;
2597 
2598  $adherentstatic->datefin = $this->db->jdate($obj->datefin);
2599  $adherentstatic->statut = $obj->statut;
2600 
2601  if ($adherentstatic->hasDelay()) {
2602  $response->nbtodolate++;
2603  }
2604  }
2605 
2606  return $response;
2607  } else {
2608  dol_print_error($this->db);
2609  $this->error = $this->db->error();
2610  return -1;
2611  }
2612  }
2613 
2614 
2626  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2627  {
2628  global $conf, $langs;
2629 
2630  $langs->load("orders");
2631 
2632  if (!dol_strlen($modele)) {
2633  $modele = 'standard';
2634 
2635  if ($this->model_pdf) {
2636  $modele = $this->model_pdf;
2637  } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2638  $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2639  }
2640  }
2641 
2642  $modelpath = "core/modules/member/doc/";
2643 
2644  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2645  }
2646 
2647 
2655  public function initAsSpecimen()
2656  {
2657  global $user, $langs;
2658  $now = dol_now();
2659 
2660  // Initialise parameters
2661  $this->id = 0;
2662  $this->ref = 'ABC001';
2663  $this->entity = 1;
2664  $this->specimen = 1;
2665  $this->civility_id = 'MR';
2666  $this->lastname = 'DOLIBARR';
2667  $this->firstname = 'SPECIMEN';
2668  $this->gender = 'man';
2669  $this->login = 'dolibspec';
2670  $this->pass = 'dolibspec';
2671  $this->company = 'Societe ABC';
2672  $this->address = '61 jump street';
2673  $this->zip = '75000';
2674  $this->town = 'Paris';
2675  $this->country_id = 1;
2676  $this->country_code = 'FR';
2677  $this->country = 'France';
2678  $this->morphy = 'mor';
2679  $this->email = 'specimen@specimen.com';
2680  $this->socialnetworks = array(
2681  'skype' => 'skypepseudo',
2682  'twitter' => 'twitterpseudo',
2683  'facebook' => 'facebookpseudo',
2684  'linkedin' => 'linkedinpseudo',
2685  );
2686  $this->phone = '0999999999';
2687  $this->phone_perso = '0999999998';
2688  $this->phone_mobile = '0999999997';
2689  $this->note_public = 'This is a public note';
2690  $this->note_private = 'This is a private note';
2691  $this->birth = $now;
2692  $this->photo = '';
2693  $this->public = 1;
2694  $this->statut = self::STATUS_DRAFT;
2695 
2696  $this->datefin = $now;
2697  $this->datevalid = $now;
2698  $this->default_lang = '';
2699 
2700  $this->typeid = 1; // Id type adherent
2701  $this->type = 'Type adherent'; // Libelle type adherent
2702  $this->need_subscription = 0;
2703 
2704  $this->first_subscription_date = $now;
2705  $this->first_subscription_date_start = $this->first_subscription_date;
2706  $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2707  $this->first_subscription_amount = 10;
2708 
2709  $this->last_subscription_date = $this->first_subscription_date;
2710  $this->last_subscription_date_start = $this->first_subscription_date;
2711  $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2712  $this->last_subscription_amount = 10;
2713  return 1;
2714  }
2715 
2716 
2717  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2718  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2728  public function _load_ldap_dn($info, $mode = 0)
2729  {
2730  // phpcs:enable
2731  global $conf;
2732  $dn = '';
2733  if ($mode == 0) {
2734  $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')]."," . getDolGlobalString('LDAP_MEMBER_DN');
2735  }
2736  if ($mode == 1) {
2737  $dn = getDolGlobalString('LDAP_MEMBER_DN');
2738  }
2739  if ($mode == 2) {
2740  $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')];
2741  }
2742  return $dn;
2743  }
2744 
2745 
2746  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2747  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2753  public function _load_ldap_info()
2754  {
2755  // phpcs:enable
2756  global $conf, $langs;
2757 
2758  $info = array();
2759  $socialnetworks = getArrayOfSocialNetworks();
2760  $keymodified = false;
2761 
2762  // Object classes
2763  $info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
2764 
2765  $this->fullname = $this->getFullName($langs);
2766 
2767  // For avoid ldap error when firstname and lastname are empty
2768  if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
2769  $this->fullname = $this->company;
2770  $this->lastname = $this->company;
2771  }
2772 
2773  // Possible LDAP KEY (constname => varname)
2774  $ldapkey = array(
2775  'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
2776  'LDAP_MEMBER_FIELD_NAME' => 'lastname',
2777  'LDAP_MEMBER_FIELD_LOGIN' => 'login',
2778  'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
2779  'LDAP_MEMBER_FIELD_MAIL' => 'email'
2780  );
2781 
2782  // Member
2783  foreach ($ldapkey as $constname => $varname) {
2784  if (!empty($this->$varname) && getDolGlobalString($constname)) {
2785  $info[getDolGlobalString($constname)] = $this->$varname;
2786 
2787  // Check if it is the LDAP key and if its value has been changed
2788  if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
2789  if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
2790  $keymodified = true; // For check if LDAP key has been modified
2791  }
2792  }
2793  }
2794  }
2795  if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
2796  $info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
2797  }
2798  if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
2799  $info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
2800  }
2801  if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
2802  $info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
2803  }
2804  if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
2805  $info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
2806  }
2807  if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
2808  $info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
2809  }
2810  if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
2811  $info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
2812  }
2813  if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
2814  $info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
2815  }
2816  foreach ($socialnetworks as $key => $value) {
2817  if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))) {
2818  $info[getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
2819  }
2820  }
2821  if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
2822  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
2823  }
2824  if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
2825  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
2826  }
2827  if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
2828  $info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
2829  }
2830  if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
2831  $info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
2832  }
2833  if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
2834  $info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
2835  }
2836  if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
2837  $info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
2838  }
2839  if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
2840  $info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
2841  }
2842  if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
2843  $info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
2844  }
2845  if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
2846  $info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
2847  }
2848 
2849  // When password is modified
2850  if (!empty($this->pass)) {
2851  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2852  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
2853  }
2854  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2855  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2856  }
2857  } elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
2858  // Set LDAP password if possible
2859  // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2860  if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
2861  // Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
2862  if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
2863  if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2864  // Create OpenLDAP MD5 password from Dolibarr MD5 password
2865  // Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
2866  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
2867  }
2868  }
2869  } elseif (!empty($this->pass_indatabase)) {
2870  // Use $this->pass_indatabase value if exists
2871  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2872  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
2873  }
2874  if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2875  $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2876  }
2877  }
2878  }
2879 
2880  // Subscriptions
2881  if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
2882  $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
2883  }
2884  if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
2885  $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
2886  }
2887  if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
2888  $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
2889  }
2890  if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
2891  $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
2892  }
2893 
2894  return $info;
2895  }
2896 
2897 
2904  public function info($id)
2905  {
2906  $sql = 'SELECT a.rowid, a.datec as datec,';
2907  $sql .= ' a.datevalid as datev,';
2908  $sql .= ' a.tms as datem,';
2909  $sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2910  $sql .= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
2911  $sql .= ' WHERE a.rowid = '.((int) $id);
2912 
2913  dol_syslog(get_class($this)."::info", LOG_DEBUG);
2914  $result = $this->db->query($sql);
2915  if ($result) {
2916  if ($this->db->num_rows($result)) {
2917  $obj = $this->db->fetch_object($result);
2918 
2919  $this->id = $obj->rowid;
2920 
2921  $this->user_creation_id = $obj->fk_user_author;
2922  $this->user_validation_id = $obj->fk_user_valid;
2923  $this->user_modification_id = $obj->fk_user_mod;
2924  $this->date_creation = $this->db->jdate($obj->datec);
2925  $this->date_validation = $this->db->jdate($obj->datev);
2926  $this->date_modification = $this->db->jdate($obj->datem);
2927  }
2928 
2929  $this->db->free($result);
2930  } else {
2931  dol_print_error($this->db);
2932  }
2933  }
2934 
2940  public function getNbOfEMailings()
2941  {
2942  $sql = "SELECT count(mc.email) as nb";
2943  $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
2944  $sql .= " WHERE mc.email = '".$this->db->escape($this->email)."'";
2945  $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec success
2946 
2947  $resql = $this->db->query($sql);
2948  if ($resql) {
2949  $obj = $this->db->fetch_object($resql);
2950  $nb = $obj->nb;
2951 
2952  $this->db->free($resql);
2953  return $nb;
2954  } else {
2955  $this->error = $this->db->error();
2956  return -1;
2957  }
2958  }
2959 
2970  public function setCategories($categories)
2971  {
2972  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
2973  return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
2974  }
2975 
2984  public static function replaceThirdparty($db, $origin_id, $dest_id)
2985  {
2986  $tables = array('adherent');
2987 
2988  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
2989  }
2990 
2996  public function hasDelay()
2997  {
2998  global $conf;
2999 
3000  //Only valid members
3001  if ($this->statut != self::STATUS_VALIDATED) {
3002  return false;
3003  }
3004  if (!$this->datefin) {
3005  return false;
3006  }
3007 
3008  $now = dol_now();
3009 
3010  return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
3011  }
3012 
3013 
3021  public function sendReminderForExpiredSubscription($daysbeforeendlist = '10')
3022  {
3023  global $conf, $langs, $mysoc, $user;
3024 
3025  $error = 0;
3026  $this->output = '';
3027  $this->error = '';
3028 
3029  $blockingerrormsg = '';
3030 
3031  if (!isModEnabled('member')) { // Should not happen. If module disabled, cron job should not be visible.
3032  $langs->load("agenda");
3033  $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3034  return 0;
3035  }
3036  if (!getDolGlobalString('MEMBER_REMINDER_EMAIL')) {
3037  $langs->load("agenda");
3038  $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3039  return 0;
3040  }
3041 
3042  $now = dol_now();
3043  $nbok = 0;
3044  $nbko = 0;
3045 
3046  $listofmembersok = array();
3047  $listofmembersko = array();
3048 
3049  $arraydaysbeforeend = explode(';', $daysbeforeendlist);
3050  foreach ($arraydaysbeforeend as $daysbeforeend) { // Loop on each delay
3051  dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
3052 
3053  if (!is_numeric($daysbeforeend)) {
3054  $blockingerrormsg = "Value for delta is not a numeric value";
3055  $nbko++;
3056  break;
3057  }
3058 
3059  $tmp = dol_getdate($now);
3060  $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), $daysbeforeend, 'd');
3061 
3062  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
3063  $sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
3064  $sql .= " AND statut = 1";
3065  $sql .= " AND datefin = '".$this->db->idate($datetosearchfor)."'";
3066  //$sql .= " LIMIT 10000";
3067 
3068  $resql = $this->db->query($sql);
3069  if ($resql) {
3070  $num_rows = $this->db->num_rows($resql);
3071 
3072  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
3073  $adherent = new Adherent($this->db);
3074  $formmail = new FormMail($this->db);
3075 
3076  $i = 0;
3077  while ($i < $num_rows) {
3078  $obj = $this->db->fetch_object($resql);
3079 
3080  $adherent->fetch($obj->rowid, '', '', '', true, true);
3081 
3082  if (empty($adherent->email)) {
3083  $nbko++;
3084  $listofmembersko[$adherent->id] = $adherent->id;
3085  } else {
3086  $adherent->fetch_thirdparty();
3087 
3088  // 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.
3089  $languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : $adherent->thirdparty->country_code);
3090  $languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
3091 
3092  // Send reminder email
3093  $outputlangs = new Translate('', $conf);
3094  $outputlangs->setDefaultLang($languagecodeformember);
3095  $outputlangs->loadLangs(array("main", "members"));
3096  dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
3097 
3098  $arraydefaultmessage = null;
3099  $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
3100 
3101  if (!empty($labeltouse)) {
3102  $arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
3103  }
3104 
3105  if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
3106  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
3107  //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
3108  complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
3109 
3110  $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
3111  $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
3112  $from = getDolGlobalString('ADHERENT_MAIL_FROM');
3113  $to = $adherent->email;
3114  $cc = getDolGlobalString('ADHERENT_CC_MAIL_FROM');
3115 
3116  $trackid = 'mem'.$adherent->id;
3117  $moreinheader = 'X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
3118 
3119  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
3120  $cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), $cc, '', 0, 1, '', '', $trackid, $moreinheader);
3121  $result = $cmail->sendfile();
3122  if (!$result) {
3123  $error++;
3124  $this->error .= $cmail->error.' ';
3125  if (!is_null($cmail->errors)) {
3126  $this->errors += $cmail->errors;
3127  }
3128  $nbko++;
3129  $listofmembersko[$adherent->id] = $adherent->id;
3130  } else {
3131  $nbok++;
3132  $listofmembersok[$adherent->id] = $adherent->id;
3133 
3134  $message = $msg;
3135  $sendto = $to;
3136  $sendtocc = '';
3137  $sendtobcc = '';
3138  $actioncode = 'EMAIL';
3139  $extraparams = '';
3140 
3141  $actionmsg = '';
3142  $actionmsg2 = $langs->transnoentities('MailSentByTo', CMailFile::getValidAddress($from, 4, 0, 1), CMailFile::getValidAddress($sendto, 4, 0, 1));
3143  if ($message) {
3144  $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
3145  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
3146  if ($sendtocc) {
3147  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".dol_escape_htmltag($sendtocc));
3148  }
3149  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject);
3150  $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":");
3151  $actionmsg = dol_concatdesc($actionmsg, $message);
3152  }
3153 
3154  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
3155 
3156  // Insert record of emails sent
3157  $actioncomm = new ActionComm($this->db);
3158 
3159  $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
3160  $actioncomm->code = 'AC_'.$actioncode;
3161  $actioncomm->label = $actionmsg2;
3162  $actioncomm->note_private = $actionmsg;
3163  $actioncomm->fk_project = 0;
3164  $actioncomm->datep = $now;
3165  $actioncomm->datef = $now;
3166  $actioncomm->percentage = -1; // Not applicable
3167  $actioncomm->socid = $adherent->thirdparty->id;
3168  $actioncomm->contact_id = 0;
3169  $actioncomm->authorid = $user->id; // User saving action
3170  $actioncomm->userownerid = $user->id; // Owner of action
3171  // Fields when action is en email (content should be added into note)
3172  $actioncomm->email_msgid = $cmail->msgid;
3173  $actioncomm->email_from = $from;
3174  $actioncomm->email_sender = '';
3175  $actioncomm->email_to = $to;
3176  $actioncomm->email_tocc = $sendtocc;
3177  $actioncomm->email_tobcc = $sendtobcc;
3178  $actioncomm->email_subject = $subject;
3179  $actioncomm->errors_to = '';
3180 
3181  $actioncomm->fk_element = $adherent->id;
3182  $actioncomm->elementtype = $adherent->element;
3183 
3184  $actioncomm->extraparams = $extraparams;
3185 
3186  $actioncomm->create($user);
3187  }
3188  } else {
3189  //$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
3190 
3191  $error++;
3192  $this->error .= "Can't find email template with label=".$labeltouse.", to use for the reminding email ";
3193 
3194  $nbko++;
3195  $listofmembersko[$adherent->id] = $adherent->id;
3196 
3197  break;
3198  }
3199  }
3200 
3201  $i++;
3202  }
3203  } else {
3204  $this->error = $this->db->lasterror();
3205  return 1;
3206  }
3207  }
3208 
3209  if ($blockingerrormsg) {
3210  $this->error = $blockingerrormsg;
3211  return 1;
3212  } else {
3213  $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
3214  $this->output .= ' Send email successfully to '.$nbok.' members';
3215  if (is_array($listofmembersok)) {
3216  $listofids = '';
3217  $i = 0;
3218  foreach ($listofmembersok as $idmember) {
3219  if ($i > 100) {
3220  $listofids .= ', ...';
3221  break;
3222  }
3223  if (empty($listofids)) {
3224  $listofids .= ' [';
3225  } else {
3226  $listofids .= ', ';
3227  }
3228  $listofids .= $idmember;
3229  $i++;
3230  }
3231  if ($listofids) {
3232  $listofids .= ']';
3233  }
3234 
3235  $this->output .= ($listofids ? ' ids='.$listofids : '');
3236  }
3237  if ($nbko) {
3238  $this->output .= ' - Canceled for '.$nbko.' member (no email or email sending error)';
3239  if (is_array($listofmembersko)) {
3240  $listofids = '';
3241  $i = 0;
3242  foreach ($listofmembersko as $idmember) {
3243  if ($i > 100) {
3244  $listofids .= ', ...';
3245  break;
3246  }
3247  if (empty($listofids)) {
3248  $listofids .= ' [';
3249  } else {
3250  $listofids .= ', ';
3251  }
3252  $listofids .= $idmember;
3253  $i++;
3254  }
3255  if ($listofids) {
3256  $listofids .= ']';
3257  }
3258  $this->output .= ($listofids ? ' ids='.$listofids : '');
3259  }
3260  }
3261  }
3262 
3263  return $nbko;
3264  }
3265 
3273  public function getKanbanView($option = '', $arraydata = null)
3274  {
3275  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
3276 
3277  $return = '<div class="box-flex-item box-flex-grow-zero">';
3278  $return .= '<div class="info-box info-box-sm">';
3279  $return .= '<span class="info-box-icon bg-infobox-action">';
3280  if (property_exists($this, 'photo') || !empty($this->photo)) {
3281  $return .= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photoref photowithmargin photologintooltip', 'small', 0, 1);
3282  } else {
3283  $return .= img_picto('', 'user');
3284  }
3285  $return .= '</span>';
3286  $return .= '<div class="info-box-content">';
3287  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
3288  if ($selected >= 0) {
3289  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
3290  }
3291  if (property_exists($this, 'type')) {
3292  $return .= '<br><span class="info-box-label opacitymedium">'.$this->type.'</span>';
3293  }
3294  if (method_exists($this, 'getmorphylib')) {
3295  $return .= '<br><span class="info-box-label">'.$this->getmorphylib('', 2).'</span>';
3296  }
3297  if (method_exists($this, 'getLibStatut')) {
3298  $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
3299  }
3300  $return .= '</div>';
3301  $return .= '</div>';
3302  $return .= '</div>';
3303  return $return;
3304  }
3305 }
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:604
$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:744
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:123
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:959
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:122
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.