dolibarr 21.0.3
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 <alexandre@inovea-conseil.com>
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
39require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
42require_once DOL_DOCUMENT_ROOT.'/core/class/commonpeople.class.php';
43
44
49{
50 use CommonPeople;
51
55 public $element = 'member';
56
60 public $table_element = 'adherent';
61
65 public $picto = 'member';
66
70 public $mesgs;
71
75 public $login;
76
80 public $pass;
81
85 public $pass_indatabase;
86
90 public $pass_indatabase_crypted;
91
95 public $fullname;
96
102 public $civility_id;
103
107 public $civility_code;
108
112 public $civility;
113
119 public $societe;
120
124 public $company;
125
131 public $fk_soc;
132
136 public $socid;
137
141 public $socialnetworks;
142
146 public $phone;
147
151 public $phone_perso;
152
156 public $phone_pro;
157
161 public $phone_mobile;
162
166 public $fax;
167
171 public $poste;
172
176 public $morphy;
177
181 public $public;
182
187 public $default_lang;
188
192 public $photo;
193
199 public $datec;
200
206 public $datem;
207
211 public $datevalid;
212
216 public $gender;
217
221 public $birth;
222
226 public $typeid;
227
231 public $type;
232
236 public $need_subscription;
237
241 public $user_id;
242
246 public $user_login;
247
251 public $datefin;
252
253
254 // Fields loaded by fetch_subscriptions() from member table
255
259 public $first_subscription_date;
260
264 public $first_subscription_date_start;
265
269 public $first_subscription_date_end;
270
274 public $first_subscription_amount;
275
279 public $last_subscription_date;
280
284 public $last_subscription_date_start;
285
289 public $last_subscription_date_end;
290
294 public $last_subscription_amount;
295
299 public $subscriptions = array();
300
304 public $ip;
305
306 // Fields loaded by fetchPartnerships() from partnership table
307
311 public $partnerships = array();
312
316 public $invoice;
317
318
360 public $fields = array(
361 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
362 'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
363 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 15, 'index' => 1),
364 'ref_ext' => array('type' => 'varchar(128)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 20),
365 'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
366 'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
367 'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
368 'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => 1, 'position' => 40),
369 'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => 3, 'position' => 45),
370 'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => 3, 'position' => 50),
371 'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
372 'fk_adherent_type' => array('type' => 'integer', 'label' => 'MemberType', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
373 'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
374 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
375 'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
376 'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
377 'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
378 'state_id' => array('type' => 'integer', 'label' => 'State', 'enabled' => 1, 'visible' => -1, 'position' => 90),
379 'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
380 'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
381 'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
382 'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
383 'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
384 'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
385 'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => 3, 'position' => 128),
386 'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
387 'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
388 'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
389 'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 145),
390 'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
391 'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
392 'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
393 'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
394 'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
395 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
396 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
397 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserCreation', 'enabled' => 1, 'visible' => 3, 'position' => 180),
398 'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModification', 'enabled' => 1, 'visible' => 3, 'position' => 185),
399 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => 3, 'position' => 190),
400 'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => 0, 'position' => 195),
401 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
402 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805),
403 'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 1000, 'arrayofkeyval' => array(-1 => 'Draft', 1 => 'Validated', 0 => 'MemberStatusResiliatedShort', -2 => 'MemberStatusExcludedShort'))
404 );
405
409 const STATUS_DRAFT = -1;
421 const STATUS_EXCLUDED = -2;
422
423
429 public function __construct($db)
430 {
431 $this->db = $db;
432 $this->statut = self::STATUS_DRAFT;
433 $this->status = self::STATUS_DRAFT;
434 // l'adherent n'est pas public par default
435 $this->public = 0;
436 $this->ismultientitymanaged = 1;
437 $this->isextrafieldmanaged = 1;
438 // les champs optionnels sont vides
439 $this->array_options = array();
440
441 $this->fields['ref_ext']['visible'] = getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT');
442 }
443
444
445 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
464 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 = '')
465 {
466 // phpcs:enable
467 dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
468
469 return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
470 }
471
489 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 = '')
490 {
491 global $conf, $langs;
492
493 // Detect if message is HTML
494 if ($msgishtml == -1) {
495 $msgishtml = 0;
496 if (dol_textishtml($text, 0)) {
497 $msgishtml = 1;
498 }
499 }
500
501 dol_syslog('sendEmail msgishtml='.$msgishtml);
502
503 $texttosend = $this->makeSubstitution($text);
504 $subjecttosend = $this->makeSubstitution($subject);
505 if ($msgishtml) {
506 $texttosend = dol_htmlentitiesbr($texttosend);
507 }
508
509 // Envoi mail confirmation
510 $from = $conf->email_from;
511 if (getDolGlobalString('ADHERENT_MAIL_FROM')) {
512 $from = getDolGlobalString('ADHERENT_MAIL_FROM');
513 }
514
515 $trackid = 'mem'.$this->id;
516
517 // Send email (substitutionarray must be done just before this)
518 include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
519 $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
520 if ($mailfile->sendfile()) {
521 return 1;
522 } else {
523 $this->error = $langs->trans("ErrorFailedToSendMail", $from, $this->email).'. '.$mailfile->error;
524 return -1;
525 }
526 }
527
528
535 public function makeSubstitution($text)
536 {
537 global $langs;
538
539 $birthday = dol_print_date($this->birth, 'day');
540
541 $msgishtml = 0;
542 if (dol_textishtml($text, 1)) {
543 $msgishtml = 1;
544 }
545
546 $infos = '';
547 if ($this->civility_id) {
548 $infos .= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
549 }
550 $infos .= $langs->transnoentities("id").": ".$this->id."\n";
551 $infos .= $langs->transnoentities("ref").": ".$this->ref."\n";
552 $infos .= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
553 $infos .= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
554 $infos .= $langs->transnoentities("Company").": ".$this->company."\n";
555 $infos .= $langs->transnoentities("Address").": ".$this->address."\n";
556 $infos .= $langs->transnoentities("Zip").": ".$this->zip."\n";
557 $infos .= $langs->transnoentities("Town").": ".$this->town."\n";
558 $infos .= $langs->transnoentities("Country").": ".$this->country."\n";
559 $infos .= $langs->transnoentities("EMail").": ".$this->email."\n";
560 $infos .= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
561 $infos .= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
562 $infos .= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
563 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
564 $infos .= $langs->transnoentities("Login").": ".$this->login."\n";
565 $infos .= $langs->transnoentities("Password").": ".$this->pass."\n";
566 }
567 $infos .= $langs->transnoentities("Birthday").": ".$birthday."\n";
568 $infos .= $langs->transnoentities("Photo").": ".$this->photo."\n";
569 $infos .= $langs->transnoentities("Public").": ".yn($this->public);
570
571 // Substitutions
572 $substitutionarray = array(
573 '__ID__' => $this->id,
574 '__REF__' => $this->ref,
575 '__MEMBER_ID__' => $this->id,
576 '__CIVILITY__' => $this->getCivilityLabel(),
577 '__FIRSTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->firstname) : ($this->firstname ? $this->firstname : ''),
578 '__LASTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->lastname) : ($this->lastname ? $this->lastname : ''),
579 '__FULLNAME__' => $msgishtml ? dol_htmlentitiesbr($this->getFullName($langs)) : $this->getFullName($langs),
580 '__COMPANY__' => $msgishtml ? dol_htmlentitiesbr($this->company) : ($this->company ? $this->company : ''),
581 '__ADDRESS__' => $msgishtml ? dol_htmlentitiesbr($this->address) : ($this->address ? $this->address : ''),
582 '__ZIP__' => $msgishtml ? dol_htmlentitiesbr($this->zip) : ($this->zip ? $this->zip : ''),
583 '__TOWN__' => $msgishtml ? dol_htmlentitiesbr($this->town) : ($this->town ? $this->town : ''),
584 '__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''),
585 '__EMAIL__' => $msgishtml ? dol_htmlentitiesbr($this->email) : ($this->email ? $this->email : ''),
586 '__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''),
587 '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($this->photo) : ($this->photo ? $this->photo : ''),
588 '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($this->login) : ($this->login ? $this->login : ''),
589 '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($this->pass) : ($this->pass ? $this->pass : ''),
590 '__PHONE__' => $msgishtml ? dol_htmlentitiesbr($this->phone) : ($this->phone ? $this->phone : ''),
591 '__PHONEPRO__' => $msgishtml ? dol_htmlentitiesbr($this->phone_perso) : ($this->phone_perso ? $this->phone_perso : ''),
592 '__PHONEMOBILE__' => $msgishtml ? dol_htmlentitiesbr($this->phone_mobile) : ($this->phone_mobile ? $this->phone_mobile : ''),
593 '__TYPE__' => $msgishtml ? dol_htmlentitiesbr($this->type) : ($this->type ? $this->type : '')
594 );
595
596 complete_substitutions_array($substitutionarray, $langs, $this);
597
598 return make_substitutions($text, $substitutionarray, $langs);
599 }
600
601
609 public function getmorphylib($morphy = '', $addbadge = 0)
610 {
611 global $langs;
612 $s = '';
613
614 // Clean var
615 if (!$morphy) {
616 $morphy = $this->morphy;
617 }
618
619 if ($addbadge) {
620 $labeltoshowm = $langs->trans("Moral");
621 $labeltoshowp = $langs->trans("Physical");
622 if ($morphy == 'phy') {
623 $labeltoshow = $labeltoshowp;
624 if ($addbadge == 2) {
625 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp));
626 if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowm))) {
627 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp, 2));
628 }
629 }
630 $s .= '<span class="member-individual-back paddingleftimp paddingrightimp" title="'.$langs->trans("Physical").'">'.$labeltoshow.'</span>';
631 }
632 if ($morphy == 'mor') {
633 $labeltoshow = $labeltoshowm;
634 if ($addbadge == 2) {
635 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm));
636 if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowp))) {
637 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm, 2));
638 }
639 }
640 $s .= '<span class="member-company-back paddingleftimp paddingrightimp" title="'.$langs->trans("Moral").'">'.$labeltoshow.'</span>';
641 }
642 } else {
643 if ($morphy == 'phy') {
644 $s = $langs->trans("Physical");
645 } elseif ($morphy == 'mor') {
646 $s = $langs->trans("Moral");
647 }
648 }
649
650 return $s;
651 }
652
660 public function create($user, $notrigger = 0)
661 {
662 global $conf, $langs, $mysoc;
663
664 $error = 0;
665
666 $now = dol_now();
667
668 // Clean parameters
669 if (isset($this->import_key)) {
670 $this->import_key = trim($this->import_key);
671 }
672
673 // Check parameters
674 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
675 $langs->load("errors");
676 $this->error = $langs->trans("ErrorBadEMail", $this->email);
677 return -1;
678 }
679 if (!$this->datec) {
680 $this->datec = $now;
681 }
682 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
683 if (empty($this->login)) {
684 $this->error = $langs->trans("ErrorWrongValueForParameterX", "Login");
685 return -1;
686 }
687 }
688
689 // setEntity will set entity with the right value if empty or change it for the right value if multicompany module is active
690 $this->entity = setEntity($this);
691
692 $this->db->begin();
693
694 // Insert member
695 $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
696 $sql .= " (ref, datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key, ip)";
697 $sql .= " VALUES (";
698 $sql .= " '(PROV)'";
699 $sql .= ", '".$this->db->idate($this->datec)."'";
700 $sql .= ", ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
701 $sql .= ", ".($user->id > 0 ? $user->id : "null"); // Can be null because member can be created by a guest or a script
702 $sql .= ", null, null, '".$this->db->escape($this->morphy)."'";
703 $sql .= ", ".((int) $this->typeid);
704 $sql .= ", ".((int) $this->entity);
705 $sql .= ", ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
706 $sql .= ", ".(!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
707 $sql .= ")";
708
709 dol_syslog(get_class($this)."::create", LOG_DEBUG);
710 $result = $this->db->query($sql);
711 if ($result) {
712 $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
713 if ($id > 0) {
714 $this->id = $id;
715 if (getDolGlobalString('MEMBER_CODEMEMBER_ADDON') == '') {
716 // keep old numbering
717 $this->ref = (string) $id;
718 } else {
719 // auto code
720 $modfile = dol_buildpath('core/modules/member/'.getDolGlobalString('MEMBER_CODEMEMBER_ADDON').'.php', 0);
721 try {
722 require_once $modfile;
723 $modname = getDolGlobalString('MEMBER_CODEMEMBER_ADDON');
724 $modCodeMember = new $modname();
725 '@phan-var-force ModeleNumRefMembers $modCodeMember';
727 $this->ref = $modCodeMember->getNextValue($mysoc, $this);
728 } catch (Exception $e) {
729 dol_syslog($e->getMessage(), LOG_ERR);
730 $error++;
731 }
732 }
733
734 // Update minor fields
735 $result = $this->update($user, 1, 1, 0, 0, 'add'); // nosync is 1 to avoid update data of user
736 if ($result < 0) {
737 $this->db->rollback();
738 return -1;
739 }
740
741 // Add link to user
742 if ($this->user_id) {
743 // Add link to user
744 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
745 $sql .= " fk_member = ".((int) $this->id);
746 $sql .= " WHERE rowid = ".((int) $this->user_id);
747 dol_syslog(get_class($this)."::create", LOG_DEBUG);
748 $resql = $this->db->query($sql);
749 if (!$resql) {
750 $this->error = 'Failed to update user to make link with member';
751 $this->db->rollback();
752 return -4;
753 }
754 }
755
756 if (!$notrigger) {
757 // Call trigger
758 $result = $this->call_trigger('MEMBER_CREATE', $user);
759 if ($result < 0) {
760 $error++;
761 }
762 // End call triggers
763 }
764
765 if (count($this->errors)) {
766 dol_syslog(get_class($this)."::create ".implode(',', $this->errors), LOG_ERR);
767 $this->db->rollback();
768 return -3;
769 } else {
770 $this->db->commit();
771 return $this->id;
772 }
773 } else {
774 $this->error = 'Failed to get last insert id';
775 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
776 $this->db->rollback();
777 return -2;
778 }
779 } else {
780 $this->error = $this->db->error();
781 $this->db->rollback();
782 return -1;
783 }
784 }
785
786
798 public function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
799 {
800 global $langs, $hookmanager;
801
802 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
803
804 $nbrowsaffected = 0;
805 $error = 0;
806
807 dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
808
809 // Clean parameters
810 $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
811 $this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
812 $this->gender = trim($this->gender);
813 // $this->address = ($this->address ? $this->address : $this->address);
814 // $this->zip = ($this->zip ? $this->zip : $this->zip);
815 // $this->town = ($this->town ? $this->town : $this->town);
816 // $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
817 // $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id);
818 // $this->note_public = ($this->note_public ? $this->note_public : $this->note_public);
819 // $this->note_private = ($this->note_private ? $this->note_private : $this->note_private);
820 $this->url = $this->url ? clean_url($this->url, 0) : '';
821 $this->setUpperOrLowerCase();
822 // Check parameters
823 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
824 $langs->load("errors");
825 $this->error = $langs->trans("ErrorBadEMail", $this->email);
826 return -1;
827 }
828
829 $this->db->begin();
830
831 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
832 $sql .= " ref = '".$this->db->escape($this->ref)."'";
833 $sql .= ", civility = ".($this->civility_id ? "'".$this->db->escape($this->civility_id)."'" : "null");
834 $sql .= ", firstname = ".($this->firstname ? "'".$this->db->escape($this->firstname)."'" : "null");
835 $sql .= ", lastname = ".($this->lastname ? "'".$this->db->escape($this->lastname)."'" : "null");
836 $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
837 $sql .= ", login = ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
838 $sql .= ", societe = ".($this->company ? "'".$this->db->escape($this->company)."'" : ($this->societe ? "'".$this->db->escape($this->societe)."'" : "null"));
839 if ($this->socid) {
840 $sql .= ", fk_soc = ".($this->socid > 0 ? (int) $this->socid : "null"); // Must be modified only when creating from a third-party
841 }
842 $sql .= ", address = ".($this->address ? "'".$this->db->escape($this->address)."'" : "null");
843 $sql .= ", zip = ".($this->zip ? "'".$this->db->escape($this->zip)."'" : "null");
844 $sql .= ", town = ".($this->town ? "'".$this->db->escape($this->town)."'" : "null");
845 $sql .= ", country = ".($this->country_id > 0 ? (int) $this->country_id : "null");
846 $sql .= ", state_id = ".($this->state_id > 0 ? (int) $this->state_id : "null");
847 $sql .= ", email = '".$this->db->escape($this->email)."'";
848 $sql .= ", url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
849 $sql .= ", socialnetworks = ".($this->socialnetworks ? "'".$this->db->escape(json_encode($this->socialnetworks))."'" : "null");
850 $sql .= ", phone = ".($this->phone ? "'".$this->db->escape($this->phone)."'" : "null");
851 $sql .= ", phone_perso = ".($this->phone_perso ? "'".$this->db->escape($this->phone_perso)."'" : "null");
852 $sql .= ", phone_mobile = ".($this->phone_mobile ? "'".$this->db->escape($this->phone_mobile)."'" : "null");
853 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
854 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
855 $sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
856 $sql .= ", public = ".(int) $this->public;
857 $sql .= ", statut = ".(int) $this->statut;
858 $sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
859 $sql .= ", fk_adherent_type = ".(int) $this->typeid;
860 $sql .= ", morphy = '".$this->db->escape($this->morphy)."'";
861 $sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null");
862
863 if ($this->datefin) {
864 $sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
865 }
866 if ($this->datevalid) {
867 $sql .= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
868 }
869 $sql .= ", fk_user_mod = ".($user->id > 0 ? $user->id : 'null'); // Can be null because member can be create by a guest
870 $sql .= " WHERE rowid = ".((int) $this->id);
871
872 // If we change the type of membership, we set also label of new type..
873 '@phan-var-force Adherent $oldcopy';
874 if (!empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid) {
875 $sql2 = "SELECT libelle as label";
876 $sql2 .= " FROM ".MAIN_DB_PREFIX."adherent_type";
877 $sql2 .= " WHERE rowid = ".((int) $this->typeid);
878 $resql2 = $this->db->query($sql2);
879 if ($resql2) {
880 while ($obj = $this->db->fetch_object($resql2)) {
881 $this->type = $obj->label;
882 }
883 }
884 }
885
886 dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
887 $resql = $this->db->query($sql);
888 if ($resql) {
889 unset($this->country_code);
890 unset($this->country);
891 unset($this->state_code);
892 unset($this->state);
893
894 $nbrowsaffected += $this->db->affected_rows($resql);
895
896 $action = 'update';
897
898 // Actions on extra fields
899 if (!$error) {
900 $result = $this->insertExtraFields();
901 if ($result < 0) {
902 $error++;
903 }
904 }
905
906 // Update password
907 if (!$error && $this->pass) {
908 dol_syslog(get_class($this)."::update update password");
909 if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) {
910 $isencrypted = getDolGlobalString('DATABASE_PWD_ENCRYPTED') ? 1 : 0;
911
912 // If password to set differs from the one found into database
913 $result = $this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
914 if (!$nbrowsaffected) {
915 $nbrowsaffected++;
916 }
917 }
918 }
919
920 // Remove links to user and replace with new one
921 if (!$error) {
922 dol_syslog(get_class($this)."::update update link to user");
923 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
924 dol_syslog(get_class($this)."::update", LOG_DEBUG);
925 $resql = $this->db->query($sql);
926 if (!$resql) {
927 $this->error = $this->db->error();
928 $this->db->rollback();
929 return -5;
930 }
931 // If there is a user linked to this member
932 if ($this->user_id > 0) {
933 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id)." WHERE rowid = ".((int) $this->user_id);
934 dol_syslog(get_class($this)."::update", LOG_DEBUG);
935 $resql = $this->db->query($sql);
936 if (!$resql) {
937 $this->error = $this->db->error();
938 $this->db->rollback();
939 return -5;
940 }
941 }
942 }
943
944 if (!$error && $nbrowsaffected) { // If something has change in main data
945 // Update information on linked user if it is an update
946 if (!$error && $this->user_id > 0 && !$nosyncuser) {
947 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
948
949 dol_syslog(get_class($this)."::update update linked user");
950
951 $luser = new User($this->db);
952 $result = $luser->fetch($this->user_id);
953
954 if ($result >= 0) {
955 //var_dump($this->user_login);exit;
956 //var_dump($this->login);exit;
957
958 // 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.
959 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
960 $luser->login = $this->login;
961 }
962
963 $luser->ref = $this->ref;
964 $luser->civility_id = $this->civility_id;
965 $luser->firstname = $this->firstname;
966 $luser->lastname = $this->lastname;
967 $luser->gender = $this->gender;
968 $luser->pass = $this->pass;
969 //$luser->socid=$this->fk_soc; // We do not enable this. This may transform a user into an external user.
970
971 $luser->birth = $this->birth;
972
973 $luser->address = $this->address;
974 $luser->zip = $this->zip;
975 $luser->town = $this->town;
976 $luser->country_id = $this->country_id;
977 $luser->state_id = $this->state_id;
978
979 $luser->email = $this->email;
980 $luser->socialnetworks = $this->socialnetworks;
981 $luser->office_phone = $this->phone;
982 $luser->user_mobile = $this->phone_mobile;
983
984 $luser->lang = $this->default_lang;
985
986 $luser->fk_member = $this->id;
987
988 $result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
989 if ($result < 0) {
990 $this->error = $luser->error;
991 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
992 $error++;
993 }
994 } else {
995 $this->error = $luser->error;
996 $error++;
997 }
998 }
999
1000 // Update information on linked thirdparty if it is an update
1001 if (!$error && $this->fk_soc > 0 && !$nosyncthirdparty) {
1002 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1003
1004 dol_syslog(get_class($this)."::update update linked thirdparty");
1005
1006 // This member is linked with a thirdparty, so we also update thirdparty information
1007 // if this is an update.
1008 $lthirdparty = new Societe($this->db);
1009 $result = $lthirdparty->fetch($this->fk_soc);
1010
1011 if ($result > 0) {
1012 $lthirdparty->address = $this->address;
1013 $lthirdparty->zip = $this->zip;
1014 $lthirdparty->town = $this->town;
1015 $lthirdparty->email = $this->email;
1016 $lthirdparty->socialnetworks = $this->socialnetworks;
1017 $lthirdparty->phone = $this->phone;
1018 $lthirdparty->state_id = $this->state_id;
1019 $lthirdparty->country_id = $this->country_id;
1020 //$lthirdparty->phone_mobile=$this->phone_mobile;
1021 $lthirdparty->default_lang = $this->default_lang;
1022
1023 $result = $lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
1024
1025 if ($result < 0) {
1026 $this->error = $lthirdparty->error;
1027 $this->errors = $lthirdparty->errors;
1028 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
1029 $error++;
1030 }
1031 } elseif ($result < 0) {
1032 $this->error = $lthirdparty->error;
1033 $error++;
1034 }
1035 }
1036 }
1037
1038 if (!$error && !$notrigger) {
1039 // Call trigger
1040 $result = $this->call_trigger('MEMBER_MODIFY', $user);
1041 if ($result < 0) {
1042 $error++;
1043 }
1044 // End call triggers
1045 }
1046
1047 if (!$error) {
1048 $this->db->commit();
1049 return $nbrowsaffected;
1050 } else {
1051 $this->db->rollback();
1052 return -1;
1053 }
1054 } else {
1055 $this->db->rollback();
1056 $this->error = $this->db->lasterror();
1057 return -2;
1058 }
1059 }
1060
1061
1062 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1070 public function update_end_date($user)
1071 {
1072 // phpcs:enable
1073 $this->db->begin();
1074
1075 // Search for last subscription id and end date
1076 $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
1077 $sql .= " FROM ".MAIN_DB_PREFIX."subscription";
1078 $sql .= " WHERE fk_adherent = ".((int) $this->id);
1079 $sql .= " ORDER by dateadh DESC"; // Sort by start subscription date
1080
1081 dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1082 $resql = $this->db->query($sql);
1083 if ($resql) {
1084 $obj = $this->db->fetch_object($resql);
1085 $dateop = $this->db->jdate($obj->dateop);
1086 $datedeb = $this->db->jdate($obj->datedeb);
1087 $datefin = $this->db->jdate($obj->datefin);
1088
1089 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1090 $sql .= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
1091 $sql .= " WHERE rowid = ".((int) $this->id);
1092
1093 dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1094 $resql = $this->db->query($sql);
1095 if ($resql) {
1096 $this->last_subscription_date = $dateop;
1097 $this->last_subscription_date_start = $datedeb;
1098 $this->last_subscription_date_end = $datefin;
1099 $this->datefin = $datefin;
1100 $this->db->commit();
1101 return 1;
1102 } else {
1103 $this->db->rollback();
1104 return -1;
1105 }
1106 } else {
1107 $this->error = $this->db->lasterror();
1108 $this->db->rollback();
1109 return -1;
1110 }
1111 }
1112
1120 public function delete($user, $notrigger = 0)
1121 {
1122 $result = 0;
1123 $error = 0;
1124 $errorflag = 0;
1125
1126 // Check parameters
1127 $rowid = $this->id;
1128
1129 $this->db->begin();
1130
1131 if (!$error && !$notrigger) {
1132 // Call trigger
1133 $result = $this->call_trigger('MEMBER_DELETE', $user);
1134 if ($result < 0) {
1135 $error++;
1136 }
1137 // End call triggers
1138 }
1139
1140 // Remove category
1141 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".((int) $rowid);
1142 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1143 $resql = $this->db->query($sql);
1144 if (!$resql) {
1145 $error++;
1146 $this->error .= $this->db->lasterror();
1147 $errorflag = -1;
1148 }
1149
1150 // Remove subscription
1151 if (!$error) {
1152 $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".((int) $rowid);
1153 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1154 $resql = $this->db->query($sql);
1155 if (!$resql) {
1156 $error++;
1157 $this->error .= $this->db->lasterror();
1158 $errorflag = -2;
1159 }
1160 }
1161
1162 // Remove linked user
1163 if (!$error) {
1164 $ret = $this->setUserId(0);
1165 if ($ret < 0) {
1166 $error++;
1167 $this->error .= $this->db->lasterror();
1168 $errorflag = -3;
1169 }
1170 }
1171
1172 // Removed extrafields
1173 if (!$error) {
1174 $result = $this->deleteExtraFields();
1175 if ($result < 0) {
1176 $error++;
1177 $errorflag = -4;
1178 dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
1179 }
1180 }
1181
1182 // Remove adherent
1183 if (!$error) {
1184 $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".((int) $rowid);
1185 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1186 $resql = $this->db->query($sql);
1187 if (!$resql) {
1188 $error++;
1189 $this->error .= $this->db->lasterror();
1190 $errorflag = -5;
1191 }
1192 }
1193
1194 if (!$error) {
1195 $this->db->commit();
1196 return 1;
1197 } else {
1198 $this->db->rollback();
1199 return $errorflag;
1200 }
1201 }
1202
1203
1214 public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
1215 {
1216 global $conf, $langs;
1217
1218 $error = 0;
1219
1220 dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." isencrypted=".$isencrypted);
1221
1222 // If new password not provided, we generate one
1223 if (!$password) {
1224 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
1225 $password = getRandomPassword(false);
1226 }
1227
1228 // Crypt password
1229 $password_crypted = dol_hash($password);
1230
1231 $password_indatabase = '';
1232 if (!$isencrypted) {
1233 $password_indatabase = $password;
1234 }
1235
1236 $this->db->begin();
1237
1238 // Mise a jour
1239 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
1240 $sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
1241 if ($isencrypted) {
1242 $sql .= ", pass = null";
1243 } else {
1244 $sql .= ", pass = '".$this->db->escape($password_indatabase)."'";
1245 }
1246 $sql .= " WHERE rowid = ".((int) $this->id);
1247
1248 //dol_syslog("Adherent::Password sql=hidden");
1249 dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1250 $result = $this->db->query($sql);
1251 if ($result) {
1252 $nbaffectedrows = $this->db->affected_rows($result);
1253
1254 if ($nbaffectedrows) {
1255 $this->pass = $password;
1256 $this->pass_indatabase = $password_indatabase;
1257 $this->pass_indatabase_crypted = $password_crypted;
1258
1259 if ($this->user_id && !$nosyncuser) {
1260 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1261
1262 // This member is linked with a user, so we also update users information
1263 // if this is an update.
1264 $luser = new User($this->db);
1265 $result = $luser->fetch($this->user_id);
1266
1267 if ($result >= 0) {
1268 $result = $luser->setPassword($user, $this->pass, 0, 0, 1);
1269 if (is_int($result) && $result < 0) {
1270 $this->error = $luser->error;
1271 dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR);
1272 $error++;
1273 }
1274 } else {
1275 $this->error = $luser->error;
1276 $error++;
1277 }
1278 }
1279
1280 if (!$error && !$notrigger) {
1281 // Call trigger
1282 $result = $this->call_trigger('MEMBER_NEW_PASSWORD', $user);
1283 if ($result < 0) {
1284 $error++;
1285 $this->db->rollback();
1286 return -1;
1287 }
1288 // End call triggers
1289 }
1290
1291 $this->db->commit();
1292 return $this->pass;
1293 } else {
1294 $this->db->rollback();
1295 return 0;
1296 }
1297 } else {
1298 $this->db->rollback();
1299 dol_print_error($this->db);
1300 return -1;
1301 }
1302 }
1303
1304
1311 public function setUserId($userid)
1312 {
1313 global $conf, $langs;
1314
1315 $this->db->begin();
1316
1317 // If user is linked to this member, remove old link to this member
1318 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
1319 dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1320 $resql = $this->db->query($sql);
1321 if (!$resql) {
1322 $this->error = $this->db->error();
1323 $this->db->rollback();
1324 return -1;
1325 }
1326
1327 // Set link to user
1328 if ($userid > 0) {
1329 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id);
1330 $sql .= " WHERE rowid = ".((int) $userid);
1331 dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1332 $resql = $this->db->query($sql);
1333 if (!$resql) {
1334 $this->error = $this->db->error();
1335 $this->db->rollback();
1336 return -2;
1337 }
1338 }
1339
1340 $this->db->commit();
1341
1342 return 1;
1343 }
1344
1345
1352 public function setThirdPartyId($thirdpartyid)
1353 {
1354 global $conf, $langs;
1355
1356 $this->db->begin();
1357
1358 // Remove link to third party onto any other members
1359 if ($thirdpartyid > 0) {
1360 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
1361 $sql .= " WHERE fk_soc = ".((int) $thirdpartyid);
1362 $sql .= " AND entity = ".$conf->entity;
1363 dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1364 $resql = $this->db->query($sql);
1365 }
1366
1367 // Add link to third party for current member
1368 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid > 0 ? (int) $thirdpartyid : 'null');
1369 $sql .= " WHERE rowid = ".((int) $this->id);
1370
1371 dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1372 $resql = $this->db->query($sql);
1373 if ($resql) {
1374 $this->db->commit();
1375 return 1;
1376 } else {
1377 $this->error = $this->db->error();
1378 $this->db->rollback();
1379 return -1;
1380 }
1381 }
1382
1383
1384 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1391 public function fetch_login($login)
1392 {
1393 // phpcs:enable
1394 global $conf;
1395
1396 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1397 $sql .= " WHERE login='".$this->db->escape($login)."'";
1398 $sql .= " AND entity = ".$conf->entity;
1399
1400 $resql = $this->db->query($sql);
1401 if ($resql) {
1402 if ($this->db->num_rows($resql)) {
1403 $obj = $this->db->fetch_object($resql);
1404 $this->fetch($obj->rowid);
1405 }
1406 } else {
1407 dol_print_error($this->db);
1408 }
1409 }
1410
1411 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1419 public function fetch_name($firstname, $lastname)
1420 {
1421 // phpcs:enable
1422 global $conf;
1423
1424 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1425 $sql .= " WHERE firstname='".$this->db->escape($firstname)."'";
1426 $sql .= " AND lastname='".$this->db->escape($lastname)."'";
1427 $sql .= " AND entity = ".$conf->entity;
1428
1429 $resql = $this->db->query($sql);
1430 if ($resql) {
1431 if ($this->db->num_rows($resql)) {
1432 $obj = $this->db->fetch_object($resql);
1433 $this->fetch($obj->rowid);
1434 }
1435 } else {
1436 dol_print_error($this->db);
1437 }
1438 }
1439
1451 public function fetch($rowid, $ref = '', $fk_soc = 0, $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
1452 {
1453 global $langs;
1454
1455 $sql = "SELECT d.rowid, d.ref, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname,";
1456 $sql .= " d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1457 $sql .= " d.note_public,";
1458 $sql .= " d.email, d.url, d.socialnetworks, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1459 $sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1460 $sql .= " d.datec as datec,";
1461 $sql .= " d.tms as datem,";
1462 $sql .= " d.datefin as datefin, d.default_lang,";
1463 $sql .= " d.birth as birthday,";
1464 $sql .= " d.datevalid as datev,";
1465 $sql .= " d.country,";
1466 $sql .= " d.state_id,";
1467 $sql .= " d.model_pdf,";
1468 $sql .= " c.rowid as country_id, c.code as country_code, c.label as country,";
1469 $sql .= " dep.nom as state, dep.code_departement as state_code,";
1470 $sql .= " t.libelle as type, t.subscription as subscription,";
1471 $sql .= " u.rowid as user_id, u.login as user_login";
1472 $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
1473 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
1474 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
1475 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
1476 $sql .= " WHERE d.fk_adherent_type = t.rowid";
1477 if ($rowid) {
1478 $sql .= " AND d.rowid=".((int) $rowid);
1479 } elseif ($ref || $fk_soc) {
1480 $sql .= " AND d.entity IN (".getEntity('adherent').")";
1481 if ($ref) {
1482 $sql .= " AND d.ref='".$this->db->escape($ref)."'";
1483 } elseif ($fk_soc > 0) {
1484 $sql .= " AND d.fk_soc=".((int) $fk_soc);
1485 }
1486 } elseif ($ref_ext) {
1487 $sql .= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
1488 }
1489
1490 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1491 $resql = $this->db->query($sql);
1492 if ($resql) {
1493 if ($this->db->num_rows($resql)) {
1494 $obj = $this->db->fetch_object($resql);
1495
1496 $this->entity = $obj->entity;
1497 $this->id = $obj->rowid;
1498 $this->ref = $obj->ref;
1499 $this->ref_ext = $obj->ref_ext;
1500
1501 $this->civility_id = $obj->civility_code; // Bad. Kept for backward compatibility
1502 $this->civility_code = $obj->civility_code;
1503 $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : '';
1504
1505 $this->firstname = $obj->firstname;
1506 $this->lastname = $obj->lastname;
1507 $this->gender = $obj->gender;
1508 $this->login = $obj->login;
1509 $this->societe = $obj->company;
1510 $this->company = $obj->company;
1511 $this->socid = $obj->fk_soc;
1512 $this->fk_soc = $obj->fk_soc; // For backward compatibility
1513 $this->address = $obj->address;
1514 $this->zip = $obj->zip;
1515 $this->town = $obj->town;
1516
1517 $this->pass = $obj->pass;
1518 $this->pass_indatabase = $obj->pass;
1519 $this->pass_indatabase_crypted = $obj->pass_crypted;
1520
1521 $this->state_id = $obj->state_id;
1522 $this->state_code = $obj->state_id ? $obj->state_code : '';
1523 $this->state = $obj->state_id ? $obj->state : '';
1524
1525 $this->country_id = $obj->country_id;
1526 $this->country_code = $obj->country_code;
1527 if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) {
1528 $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
1529 } else {
1530 $this->country = $obj->country;
1531 }
1532
1533 $this->phone = $obj->phone;
1534 $this->phone_perso = $obj->phone_perso;
1535 $this->phone_mobile = $obj->phone_mobile;
1536 $this->email = $obj->email;
1537 $this->url = $obj->url;
1538
1539 $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1540
1541 $this->photo = $obj->photo;
1542 $this->statut = $obj->statut;
1543 $this->status = $obj->statut;
1544 $this->public = $obj->public;
1545
1546 $this->datec = $this->db->jdate($obj->datec);
1547 $this->date_creation = $this->db->jdate($obj->datec);
1548 $this->datem = $this->db->jdate($obj->datem);
1549 $this->date_modification = $this->db->jdate($obj->datem);
1550 $this->datefin = $this->db->jdate($obj->datefin);
1551 $this->datevalid = $this->db->jdate($obj->datev);
1552 $this->date_validation = $this->db->jdate($obj->datev);
1553 $this->birth = $this->db->jdate($obj->birthday);
1554
1555 $this->default_lang = $obj->default_lang;
1556
1557 $this->note_private = $obj->note_private;
1558 $this->note_public = $obj->note_public;
1559 $this->morphy = $obj->morphy;
1560
1561 $this->typeid = $obj->fk_adherent_type;
1562 $this->type = $obj->type;
1563 $this->need_subscription = $obj->subscription;
1564
1565 $this->user_id = $obj->user_id;
1566 $this->user_login = $obj->user_login;
1567
1568 $this->model_pdf = $obj->model_pdf;
1569
1570 // Retrieve all extrafield
1571 // fetch optionals attributes and labels
1572 if ($fetch_optionals) {
1573 $this->fetch_optionals();
1574 }
1575
1576 // Load other properties
1577 if ($fetch_subscriptions) {
1578 $result = $this->fetch_subscriptions();
1579 }
1580
1581 return $this->id;
1582 } else {
1583 return 0;
1584 }
1585 } else {
1586 $this->error = $this->db->lasterror();
1587 return -1;
1588 }
1589 }
1590
1591
1592 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1601 public function fetch_subscriptions()
1602 {
1603 // phpcs:enable
1604 global $langs;
1605
1606 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1607
1608 $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
1609 $sql .= " c.tms as datem,";
1610 $sql .= " c.datec as datec,";
1611 $sql .= " c.dateadh as dateh,";
1612 $sql .= " c.datef as datef";
1613 $sql .= " FROM ".MAIN_DB_PREFIX."subscription as c";
1614 $sql .= " WHERE c.fk_adherent = ".((int) $this->id);
1615 $sql .= " ORDER BY c.dateadh";
1616 dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
1617
1618 $resql = $this->db->query($sql);
1619 if ($resql) {
1620 $this->subscriptions = array();
1621
1622 $i = 0;
1623 while ($obj = $this->db->fetch_object($resql)) {
1624 if ($i == 0) {
1625 $this->first_subscription_date = $this->db->jdate($obj->datec);
1626 $this->first_subscription_date_start = $this->db->jdate($obj->dateh);
1627 $this->first_subscription_date_end = $this->db->jdate($obj->datef);
1628 $this->first_subscription_amount = $obj->subscription;
1629 }
1630 $this->last_subscription_date = $this->db->jdate($obj->datec);
1631 $this->last_subscription_date_start = $this->db->jdate($obj->dateh);
1632 $this->last_subscription_date_end = $this->db->jdate($obj->datef);
1633 $this->last_subscription_amount = $obj->subscription;
1634
1635 $subscription = new Subscription($this->db);
1636 $subscription->id = $obj->rowid;
1637 $subscription->fk_adherent = $obj->fk_adherent;
1638 $subscription->fk_type = $obj->fk_type;
1639 $subscription->amount = $obj->subscription;
1640 $subscription->note = $obj->note_public;
1641 $subscription->note_public = $obj->note_public;
1642 $subscription->fk_bank = $obj->fk_bank;
1643 $subscription->datem = $this->db->jdate($obj->datem);
1644 $subscription->datec = $this->db->jdate($obj->datec);
1645 $subscription->dateh = $this->db->jdate($obj->dateh);
1646 $subscription->datef = $this->db->jdate($obj->datef);
1647
1648 $this->subscriptions[] = $subscription;
1649
1650 $i++;
1651 }
1652 return 1;
1653 } else {
1654 $this->error = $this->db->error().' sql='.$sql;
1655 return -1;
1656 }
1657 }
1658
1659
1666 public function fetchPartnerships($mode)
1667 {
1668 global $langs;
1669
1670 require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php';
1671
1672
1673 $this->partnerships[] = array();
1674
1675 return 1;
1676 }
1677
1678
1694 public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
1695 {
1696 global $user;
1697
1698 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1699
1700 $error = 0;
1701
1702 // Clean parameters
1703 if (!$amount) {
1704 $amount = 0;
1705 }
1706
1707 $this->db->begin();
1708
1709 if ($datesubend) {
1710 $datefin = $datesubend;
1711 } else {
1712 // If no end date, end date = date + 1 year - 1 day
1713 $datefin = dol_time_plus_duree($date, 1, 'y');
1714 $datefin = dol_time_plus_duree($datefin, -1, 'd');
1715 }
1716
1717 // Create subscription
1718 $subscription = new Subscription($this->db);
1719 $subscription->fk_adherent = $this->id;
1720 $subscription->dateh = $date; // Date of new subscription
1721 $subscription->datef = $datefin; // End data of new subscription
1722 $subscription->amount = $amount;
1723 $subscription->note = $label; // deprecated
1724 $subscription->note_public = $label;
1725 $subscription->fk_type = $fk_type;
1726
1727 if (empty($subscription->user_creation_id)) {
1728 $subscription->user_creation_id = $user->id;
1729 }
1730
1731 $rowid = $subscription->create($user);
1732 if ($rowid > 0) {
1733 // Update denormalized subscription end date (read database subscription to find values)
1734 // This will also update this->datefin
1735 $result = $this->update_end_date($user);
1736 if ($result > 0) {
1737 // Change properties of object (used by triggers)
1738 $this->last_subscription_date = dol_now();
1739 $this->last_subscription_date_start = $date;
1740 $this->last_subscription_date_end = $datefin;
1741 $this->last_subscription_amount = $amount;
1742 }
1743
1744 if (!$error) {
1745 $this->db->commit();
1746 return $rowid;
1747 } else {
1748 $this->db->rollback();
1749 return -2;
1750 }
1751 } else {
1752 $this->setErrorsFromObject($subscription);
1753 $this->db->rollback();
1754 return -1;
1755 }
1756 }
1757
1758
1778 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 = '')
1779 {
1780 global $conf, $langs, $user, $mysoc;
1781
1782 $error = 0;
1783
1784 $this->invoice = null; // This will contains invoice if an invoice is created
1785
1786 dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".
1787 $paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
1788
1789 // Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
1790 if ($option == 'bankdirect' && $accountid) {
1791 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1792
1793 $acct = new Account($this->db);
1794 $result = $acct->fetch($accountid);
1795
1796 $dateop = $paymentdate;
1797
1798 $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, 0, $user, $emetteur_nom, $emetteur_banque);
1799 if ($insertid > 0) {
1800 $inserturlid = $acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
1801 if ($inserturlid > 0) {
1802 // Update table subscription
1803 $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".((int) $insertid);
1804 $sql .= " WHERE rowid=".((int) $subscriptionid);
1805
1806 dol_syslog("subscription::subscription", LOG_DEBUG);
1807 $resql = $this->db->query($sql);
1808 if (!$resql) {
1809 $error++;
1810 $this->error = $this->db->lasterror();
1811 $this->errors[] = $this->error;
1812 }
1813 } else {
1814 $error++;
1815 $this->setErrorsFromObject($acct);
1816 }
1817 } else {
1818 $error++;
1819 $this->setErrorsFromObject($acct);
1820 }
1821 }
1822
1823 // If option chosen, we create invoice
1824 if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
1825 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1826 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
1827
1828 $invoice = new Facture($this->db);
1829 $customer = new Societe($this->db);
1830
1831 if (!$error) {
1832 if (!($this->fk_soc > 0)) { // If not yet linked to a company
1833 if ($autocreatethirdparty) {
1834 // Create a linked thirdparty to member
1835 $companyalias = '';
1836 $fullname = $this->getFullName($langs);
1837
1838 if ($this->morphy == 'mor') {
1839 $companyname = $this->company;
1840 if (!empty($fullname)) {
1841 $companyalias = $fullname;
1842 }
1843 } else {
1844 $companyname = $fullname;
1845 if (!empty($this->company)) {
1846 $companyalias = $this->company;
1847 }
1848 }
1849
1850 $result = $customer->create_from_member($this, $companyname, $companyalias);
1851 if ($result < 0) {
1852 $this->error = $customer->error;
1853 $this->errors = $customer->errors;
1854 $error++;
1855 } else {
1856 $this->fk_soc = $result;
1857 }
1858 } else {
1859 $langs->load("errors");
1860 $this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1861 $this->errors[] = $this->error;
1862 $error++;
1863 }
1864 }
1865 }
1866 if (!$error) {
1867 $result = $customer->fetch($this->fk_soc);
1868 if ($result <= 0) {
1869 $this->error = $customer->error;
1870 $this->errors = $customer->errors;
1871 $error++;
1872 }
1873 }
1874
1875 if (!$error) {
1876 // Create draft invoice
1877 $invoice->type = Facture::TYPE_STANDARD;
1878 $invoice->cond_reglement_id = $customer->cond_reglement_id;
1879 if (empty($invoice->cond_reglement_id)) {
1880 $paymenttermstatic = new PaymentTerm($this->db);
1881 $invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
1882 if (empty($invoice->cond_reglement_id)) {
1883 $error++;
1884 $this->error = 'ErrorNoPaymentTermRECEPFound';
1885 $this->errors[] = $this->error;
1886 }
1887 }
1888 $invoice->socid = $this->fk_soc;
1889 // set customer's payment bank account on the invoice
1890 if (!empty($customer->fk_account)) {
1891 $invoice->fk_account = $customer->fk_account;
1892 } elseif (getDolGlobalString('FACTURE_RIB_NUMBER')) {
1893 // set default bank account from invoice module settings
1894 $invoice->fk_account = (int) getDolGlobalString('FACTURE_RIB_NUMBER');
1895 }
1896 //set customer's payment method on the invoice
1897 if (!empty($customer->mode_reglement_id)) {
1898 $invoice->mode_reglement_id = $customer->mode_reglement_id;
1899 }
1900 //$invoice->date = $datesubscription;
1901 $invoice->date = dol_now();
1902
1903 // Possibility to add external linked objects with hooks
1904 $invoice->linked_objects['subscription'] = $subscriptionid;
1905 if (GETPOSTISARRAY('other_linked_objects')) {
1906 $invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int'));
1907 }
1908
1909 $result = $invoice->create($user);
1910 if ($result <= 0) {
1911 $this->error = $invoice->error;
1912 $this->errors = $invoice->errors;
1913 $error++;
1914 } else {
1915 $this->invoice = $invoice;
1916 }
1917 }
1918
1919 if (!$error) {
1920 // Add line to draft invoice
1921 $idprodsubscription = 0;
1922 if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
1923 $idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
1924 }
1925
1926 $vattouse = 0;
1927 if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
1928 $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
1929 }
1930 //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1931 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1932 $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, 0, 'TTC', $amount, 1);
1933 if ($result <= 0) {
1934 $this->error = $invoice->error;
1935 $this->errors = $invoice->errors;
1936 $error++;
1937 }
1938 }
1939
1940 if (!$error) {
1941 // Validate invoice
1942 $result = $invoice->validate($user);
1943 if ($result <= 0) {
1944 $this->error = $invoice->error;
1945 $this->errors = $invoice->errors;
1946 $error++;
1947 }
1948 }
1949
1950 if (!$error) {
1951 // TODO Link invoice with subscription ?
1952 }
1953
1954 // Add payment onto invoice
1955 if (!$error && $option == 'bankviainvoice' && $accountid) {
1956 require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1957 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1958 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
1959
1960 $amounts = array();
1961 $amounts[$invoice->id] = (float) price2num($amount);
1962
1963 $paiement = new Paiement($this->db);
1964 $paiement->datepaye = $paymentdate;
1965 $paiement->amounts = $amounts;
1966 $paiement->paiementcode = $operation;
1967 $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
1968 $paiement->num_payment = $num_chq;
1969 $paiement->note_public = $label;
1970 $paiement->ext_payment_id = $ext_payment_id;
1971 $paiement->ext_payment_site = $ext_payment_site;
1972
1973 if (!$error) {
1974 // Create payment line for invoice
1975 $paiement_id = $paiement->create($user);
1976 if (!($paiement_id > 0)) {
1977 $this->error = $paiement->error;
1978 $this->errors = $paiement->errors;
1979 $error++;
1980 }
1981 }
1982
1983 if (!$error) {
1984 // Add transaction into bank account
1985 $bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
1986 if (!($bank_line_id > 0)) {
1987 $this->error = $paiement->error;
1988 $this->errors = $paiement->errors;
1989 $error++;
1990 }
1991 }
1992
1993 if (!$error && !empty($bank_line_id)) {
1994 // Update fk_bank into subscription table
1995 $sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.((int) $bank_line_id);
1996 $sql .= ' WHERE rowid='.((int) $subscriptionid);
1997
1998 $result = $this->db->query($sql);
1999 if (!$result) {
2000 $error++;
2001 }
2002 }
2003
2004 if (!$error) {
2005 // Set invoice as paid
2006 $invoice->setPaid($user);
2007 }
2008 }
2009
2010 if (!$error) {
2011 // Define output language
2012 $outputlangs = $langs;
2013 $newlang = '';
2014 $lang_id = GETPOST('lang_id');
2015 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
2016 $newlang = $lang_id;
2017 }
2018 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
2019 $newlang = $customer->default_lang;
2020 }
2021 if (!empty($newlang)) {
2022 $outputlangs = new Translate("", $conf);
2023 $outputlangs->setDefaultLang($newlang);
2024 }
2025 // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
2026 //if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
2027
2028 $invoice->generateDocument($invoice->model_pdf, $outputlangs);
2029 }
2030 }
2031
2032 if ($error) {
2033 return -1;
2034 } else {
2035 return 1;
2036 }
2037 }
2038
2039
2046 public function validate($user)
2047 {
2048 global $langs, $conf;
2049
2050 $error = 0;
2051 $now = dol_now();
2052
2053 // Check parameters
2054 if ($this->statut == self::STATUS_VALIDATED) {
2055 dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
2056 return 0;
2057 }
2058
2059 $this->db->begin();
2060
2061 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2062 $sql .= " statut = ".self::STATUS_VALIDATED;
2063 $sql .= ", datevalid = '".$this->db->idate($now)."'";
2064 $sql .= ", fk_user_valid = ".((int) $user->id);
2065 $sql .= " WHERE rowid = ".((int) $this->id);
2066
2067 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
2068 $result = $this->db->query($sql);
2069 if ($result) {
2070 $this->statut = self::STATUS_VALIDATED;
2071
2072 // Call trigger
2073 $result = $this->call_trigger('MEMBER_VALIDATE', $user);
2074 if ($result < 0) {
2075 $error++;
2076 $this->db->rollback();
2077 return -1;
2078 }
2079 // End call triggers
2080
2081 $this->datevalid = $now;
2082
2083 $this->db->commit();
2084 return 1;
2085 } else {
2086 $this->error = $this->db->error();
2087 $this->db->rollback();
2088 return -1;
2089 }
2090 }
2091
2092
2099 public function resiliate($user)
2100 {
2101 global $langs, $conf;
2102
2103 $error = 0;
2104
2105 // Check parameters
2106 if ($this->statut == self::STATUS_RESILIATED) {
2107 dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2108 return 0;
2109 }
2110
2111 $this->db->begin();
2112
2113 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2114 $sql .= " statut = ".self::STATUS_RESILIATED;
2115 $sql .= ", fk_user_valid=".$user->id;
2116 $sql .= " WHERE rowid = ".((int) $this->id);
2117
2118 $result = $this->db->query($sql);
2119 if ($result) {
2120 $this->statut = self::STATUS_RESILIATED;
2121
2122 // Call trigger
2123 $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2124 if ($result < 0) {
2125 $error++;
2126 $this->db->rollback();
2127 return -1;
2128 }
2129 // End call triggers
2130
2131 $this->db->commit();
2132 return 1;
2133 } else {
2134 $this->error = $this->db->error();
2135 $this->db->rollback();
2136 return -1;
2137 }
2138 }
2139
2149 public function exclude($user)
2150 {
2151 $error = 0;
2152
2153 // Check parameters
2154 if ($this->statut == self::STATUS_EXCLUDED) {
2155 dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2156 return 0;
2157 }
2158
2159 $this->db->begin();
2160
2161 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2162 $sql .= " statut = ".self::STATUS_EXCLUDED;
2163 $sql .= ", fk_user_valid=".$user->id;
2164 $sql .= " WHERE rowid = ".((int) $this->id);
2165
2166 $result = $this->db->query($sql);
2167 if ($result) {
2168 $this->statut = self::STATUS_EXCLUDED;
2169
2170 // Call trigger
2171 $result = $this->call_trigger('MEMBER_EXCLUDE', $user);
2172 if ($result < 0) {
2173 $error++;
2174 $this->db->rollback();
2175 return -1;
2176 }
2177 // End call triggers
2178
2179 $this->db->commit();
2180 return 1;
2181 } else {
2182 $this->error = $this->db->error();
2183 $this->db->rollback();
2184 return -1;
2185 }
2186 }
2187
2188 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2194 public function add_to_abo()
2195 {
2196 // phpcs:enable
2197 global $langs;
2198
2199 include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2200 $mailmanspip = new MailmanSpip($this->db);
2201
2202 $err = 0;
2203
2204 // mailman
2205 if (getDolGlobalString('ADHERENT_USE_MAILMAN') && isModEnabled('mailmanspip')) {
2206 $result = $mailmanspip->add_to_mailman($this);
2207
2208 if ($result < 0) {
2209 if (!empty($mailmanspip->error)) {
2210 $this->errors[] = $mailmanspip->error;
2211 }
2212 $err += 1;
2213 }
2214 foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) {
2215 $langs->load("errors");
2216 $this->errors[] = $langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
2217 }
2218 foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) {
2219 $langs->load("mailmanspip");
2220 $this->mesgs[] = $langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
2221 }
2222 }
2223
2224 // spip
2225 if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2226 $result = $mailmanspip->add_to_spip($this);
2227 if ($result < 0) {
2228 $this->errors[] = $mailmanspip->error;
2229 $err += 1;
2230 }
2231 }
2232 if ($err) {
2233 return -$err;
2234 } else {
2235 return 1;
2236 }
2237 }
2238
2239
2240 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2246 public function del_to_abo()
2247 {
2248 // phpcs:enable
2249 global $conf, $langs;
2250
2251 include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2252 $mailmanspip = new MailmanSpip($this->db);
2253
2254 $err = 0;
2255
2256 // mailman
2257 if (getDolGlobalString('ADHERENT_USE_MAILMAN')) {
2258 $result = $mailmanspip->del_to_mailman($this);
2259 if ($result < 0) {
2260 if (!empty($mailmanspip->error)) {
2261 $this->errors[] = $mailmanspip->error;
2262 }
2263 $err += 1;
2264 }
2265
2266 foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) {
2267 $langs->load("errors");
2268 $this->errors[] = $langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
2269 }
2270 foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) {
2271 $langs->load("mailmanspip");
2272 $this->mesgs[] = $langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
2273 }
2274 }
2275
2276 if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2277 $result = $mailmanspip->del_to_spip($this);
2278 if ($result < 0) {
2279 $this->errors[] = $mailmanspip->error;
2280 $err += 1;
2281 }
2282 }
2283 if ($err) {
2284 // error
2285 return -$err;
2286 } else {
2287 return 1;
2288 }
2289 }
2290
2291
2297 public function getCivilityLabel()
2298 {
2299 global $langs;
2300 $langs->load("dict");
2301
2302 $code = (empty($this->civility_id) ? '' : $this->civility_id);
2303 if (empty($code)) {
2304 return '';
2305 }
2306 return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
2307 }
2308
2315 public function getTooltipContentArray($params)
2316 {
2317 global $langs;
2318
2319 $langs->loadLangs(['members', 'companies']);
2320 $nofetch = !empty($params['nofetch']);
2321
2322 $datas = array();
2323
2324 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2325 $langs->load("users");
2326 return ['optimize' => $langs->trans("ShowUser")];
2327 }
2328 if (!empty($this->photo)) {
2329 $photo = '<div class="photointooltip floatright">';
2330 $photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1);
2331 $photo .= '</div>';
2332 $datas['photo'] = $photo;
2333 }
2334
2335 $datas['divopen'] = '<div class="centpercent">';
2336 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Member").'</u> '.$this->getLibStatut(4);
2337 if (!empty($this->morphy)) {
2338 $datas['picto'] .= '&nbsp;' . $this->getmorphylib('', 1);
2339 }
2340 if (!empty($this->ref)) {
2341 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
2342 }
2343 if (!empty($this->login)) {
2344 $datas['login'] = '<br><b>'.$langs->trans('Login').':</b> '.$this->login;
2345 }
2346 if (!empty($this->firstname) || !empty($this->lastname)) {
2347 $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
2348 }
2349 if (!empty($this->company)) {
2350 $datas['company'] = '<br><b>'.$langs->trans('Company').':</b> '.$this->company;
2351 }
2352 if (!empty($this->email)) {
2353 $datas['email'] = '<br><b>'.$langs->trans("EMail").':</b> '.$this->email;
2354 }
2355 $datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs);
2356 // show categories for this record only in ajax to not overload lists
2357 if (isModEnabled('category') && !$nofetch) {
2358 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
2359 $form = new Form($this->db);
2360 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_MEMBER, 1);
2361 }
2362 $datas['divclose'] = '</div>';
2363
2364 return $datas;
2365 }
2366
2380 public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0)
2381 {
2382 global $conf, $langs, $hookmanager;
2383
2384 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpictoimg) {
2385 $withpictoimg = 0;
2386 }
2387
2388 $result = '';
2389 $linkstart = '';
2390 $linkend = '';
2391 $classfortooltip = 'classfortooltip';
2392 $dataparams = '';
2393 $params = [
2394 'id' => $this->id,
2395 'objecttype' => $this->element,
2396 'option' => $option,
2397 'nofetch' => 1,
2398 ];
2399 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
2400 $classfortooltip = 'classforajaxtooltip';
2401 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
2402 $label = '';
2403 } else {
2404 $label = implode($this->getTooltipContentArray($params));
2405 }
2406
2407 $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.((int) $this->id);
2408 if ($option == 'subscription') {
2409 $url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.((int) $this->id);
2410 }
2411
2412 if ($option != 'nolink') {
2413 // Add param to save lastsearch_values or not
2414 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2415 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
2416 $add_save_lastsearch_values = 1;
2417 }
2418 if ($add_save_lastsearch_values) {
2419 $url .= '&save_lastsearch_values=1';
2420 }
2421 }
2422
2423 $linkstart .= '<a href="'.$url.'"';
2424 $linkclose = "";
2425 if (empty($notooltip)) {
2426 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2427 $langs->load("users");
2428 $label = $langs->trans("ShowUser");
2429 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
2430 }
2431 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
2432 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
2433 }
2434
2435 $linkstart .= $linkclose.'>';
2436 $linkend = '</a>';
2437
2438 $result .= $linkstart;
2439
2440 if ($withpictoimg) {
2441 $paddafterimage = '';
2442 if (abs($withpictoimg) == 1 || abs($withpictoimg) == 4) {
2443 $morecss .= ' paddingrightonly';
2444 }
2445 // Only picto
2446 if ($withpictoimg > 0) {
2447 $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1).'</span>';
2448 } else {
2449 // Picto must be a photo
2450 $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'"'.($paddafterimage ? ' '.$paddafterimage : '').'>';
2451 $picto .= Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.(($withpictoimg == -3 || $withpictoimg == -4) ? 'small' : ''), 'mini', 0, 1);
2452 $picto .= '</span>';
2453 }
2454 $result .= $picto;
2455 }
2456 if (($withpictoimg > -2 && $withpictoimg != 2) || $withpictoimg == -4) {
2457 if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2458 $result .= '<span class="nopadding valignmiddle'.((!isset($this->statut) || $this->statut) ? '' : ' strikefordisabled').
2459 ($morecss ? ' usertext'.$morecss : '').'">';
2460 }
2461 if ($mode == 'login') {
2462 $result .= dol_trunc($this->login, $maxlen);
2463 } elseif ($mode == 'ref') {
2464 $result .= $this->ref;
2465 } else {
2466 $result .= $this->getFullName($langs, 0, ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2467 }
2468 if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2469 $result .= '</span>';
2470 }
2471 }
2472
2473 $result .= $linkend;
2474
2475 if ($addlinktonotes) {
2476 if ($this->note_private) {
2477 $notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($this->note_private, 1);
2478 $result .= ' <span class="note inline-block">';
2479 $result .= '<a href="'.DOL_URL_ROOT.'/adherents/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
2480 $result .= img_picto('', 'note');
2481 $result .= '</a>';
2482 $result .= '</span>';
2483 }
2484 }
2485 global $action;
2486 $hookmanager->initHooks(array($this->element . 'dao'));
2487 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
2488 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2489 if ($reshook > 0) {
2490 $result = $hookmanager->resPrint;
2491 } else {
2492 $result .= $hookmanager->resPrint;
2493 }
2494 return $result;
2495 }
2496
2503 public function getLibStatut($mode = 0)
2504 {
2505 return $this->LibStatut($this->status, $this->need_subscription, $this->datefin, $mode);
2506 }
2507
2508 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2518 public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
2519 {
2520 // phpcs:enable
2521 global $langs;
2522 $langs->load("members");
2523
2524 $statusType = '';
2525 $labelStatus = '';
2526 $labelStatusShort = '';
2527
2528 if ($status == self::STATUS_DRAFT) {
2529 $statusType = 'status0';
2530 $labelStatus = $langs->trans("MemberStatusDraft");
2531 $labelStatusShort = $langs->trans("MemberStatusDraftShort");
2532 } elseif ($status >= self::STATUS_VALIDATED) {
2533 if ($need_subscription === 0) {
2534 $statusType = 'status4';
2535 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusNoSubscription");
2536 $labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
2537 } elseif (!$date_end_subscription) {
2538 $statusType = 'status1';
2539 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("WaitingSubscription");
2540 $labelStatusShort = $langs->trans("WaitingSubscriptionShort");
2541 } elseif ($date_end_subscription < dol_now()) { // expired
2542 $statusType = 'status8';
2543 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusActiveLate");
2544 $labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
2545 } else {
2546 $statusType = 'status4';
2547 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusPaid");
2548 $labelStatusShort = $langs->trans("MemberStatusPaidShort");
2549 }
2550 } elseif ($status == self::STATUS_RESILIATED) {
2551 $statusType = 'status6';
2552 $labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
2553 $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
2554 } elseif ($status == self::STATUS_EXCLUDED) {
2555 $statusType = 'status10';
2556 $labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
2557 $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
2558 }
2559
2560 return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
2561 }
2562
2563
2569 public function loadStateBoard()
2570 {
2571 global $conf;
2572
2573 $this->nb = array();
2574
2575 $sql = "SELECT count(a.rowid) as nb";
2576 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2577 $sql .= " WHERE a.statut > 0";
2578 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2579
2580 $resql = $this->db->query($sql);
2581 if ($resql) {
2582 while ($obj = $this->db->fetch_object($resql)) {
2583 $this->nb["members"] = $obj->nb;
2584 }
2585 $this->db->free($resql);
2586 return 1;
2587 } else {
2588 dol_print_error($this->db);
2589 $this->error = $this->db->error();
2590 return -1;
2591 }
2592 }
2593
2594 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2602 public function load_board($user, $mode)
2603 {
2604 // phpcs:enable
2605 global $conf, $langs;
2606
2607 if ($user->socid) {
2608 return -1; // protection pour eviter appel par utilisateur externe
2609 }
2610
2611 $now = dol_now();
2612
2613 $sql = "SELECT a.rowid, a.datefin, a.statut";
2614 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2615 $sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
2616 $sql .= " WHERE a.fk_adherent_type = t.rowid";
2617 if ($mode == 'expired') {
2618 $sql .= " AND a.statut = ".self::STATUS_VALIDATED;
2619 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2620 $sql .= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = '1')";
2621 } elseif ($mode == 'shift') {
2622 $sql .= " AND a.statut = ".self::STATUS_DRAFT;
2623 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2624 }
2625
2626 $resql = $this->db->query($sql);
2627 if ($resql) {
2628 $langs->load("members");
2629
2630 $warning_delay = 0;
2631 $url = '';
2632 $label = '';
2633 $labelShort = '';
2634
2635 if ($mode == 'expired') {
2636 $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2637 $label = $langs->trans("MembersWithSubscriptionToReceive");
2638 $labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
2639 $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_VALIDATED.'&amp;filter=outofdate';
2640 } elseif ($mode == 'shift') {
2641 $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2642 $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_DRAFT;
2643 $label = $langs->trans("MembersListToValid");
2644 $labelShort = $langs->trans("ToValidate");
2645 }
2646
2647 $response = new WorkboardResponse();
2648 $response->warning_delay = $warning_delay;
2649 $response->label = $label;
2650 $response->labelShort = $labelShort;
2651 $response->url = $url;
2652 $response->img = img_object('', "user");
2653
2654 $adherentstatic = new Adherent($this->db);
2655
2656 while ($obj = $this->db->fetch_object($resql)) {
2657 $response->nbtodo++;
2658
2659 $adherentstatic->datefin = $this->db->jdate($obj->datefin);
2660 $adherentstatic->statut = $obj->statut;
2661
2662 if ($adherentstatic->hasDelay()) {
2663 $response->nbtodolate++;
2664 }
2665 }
2666
2667 return $response;
2668 } else {
2669 dol_print_error($this->db);
2670 $this->error = $this->db->error();
2671 return -1;
2672 }
2673 }
2674
2675
2687 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2688 {
2689 global $conf, $langs;
2690
2691 $langs->load("orders");
2692
2693 if (!dol_strlen($modele)) {
2694 $modele = 'standard';
2695
2696 if ($this->model_pdf) {
2697 $modele = $this->model_pdf;
2698 } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2699 $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2700 }
2701 }
2702
2703 $modelpath = "core/modules/member/doc/";
2704
2705 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2706 }
2707
2708
2716 public function initAsSpecimen()
2717 {
2718 global $user, $langs;
2719 $now = dol_now();
2720
2721 // Initialise parameters
2722 $this->id = 0;
2723 $this->ref = 'ABC001';
2724 $this->entity = 1;
2725 $this->specimen = 1;
2726 $this->civility_id = 'MR';
2727 $this->lastname = 'DOLIBARR';
2728 $this->firstname = 'SPECIMEN';
2729 $this->gender = 'man';
2730 $this->login = 'dolibspec';
2731 $this->pass = 'dolibspec';
2732 $this->company = 'Societe ABC';
2733 $this->address = '61 jump street';
2734 $this->zip = '75000';
2735 $this->town = 'Paris';
2736 $this->country_id = 1;
2737 $this->country_code = 'FR';
2738 $this->country = 'France';
2739 $this->morphy = 'mor';
2740 $this->email = 'specimen@specimen.com';
2741 $this->socialnetworks = array(
2742 'skype' => 'skypepseudo',
2743 'twitter' => 'twitterpseudo',
2744 'facebook' => 'facebookpseudo',
2745 'linkedin' => 'linkedinpseudo',
2746 );
2747 $this->phone = '0999999999';
2748 $this->phone_perso = '0999999998';
2749 $this->phone_mobile = '0999999997';
2750 $this->note_public = 'This is a public note';
2751 $this->note_private = 'This is a private note';
2752 $this->birth = $now;
2753 $this->photo = '';
2754 $this->public = 1;
2755 $this->statut = self::STATUS_DRAFT;
2756 $this->status = self::STATUS_DRAFT;
2757
2758 $this->datefin = $now;
2759 $this->datevalid = $now;
2760 $this->default_lang = '';
2761
2762 $this->typeid = 1; // Id type adherent
2763 $this->type = 'Type adherent'; // Libelle type adherent
2764 $this->need_subscription = 0;
2765
2766 $this->first_subscription_date = $now;
2767 $this->first_subscription_date_start = $this->first_subscription_date;
2768 $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2769 $this->first_subscription_amount = 10;
2770
2771 $this->last_subscription_date = $this->first_subscription_date;
2772 $this->last_subscription_date_start = $this->first_subscription_date;
2773 $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2774 $this->last_subscription_amount = 10;
2775 return 1;
2776 }
2777
2778
2779 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2780 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2790 public function _load_ldap_dn($info, $mode = 0)
2791 {
2792 // phpcs:enable
2793 global $conf;
2794 $dn = '';
2795 if ($mode == 0) {
2796 $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')]."," . getDolGlobalString('LDAP_MEMBER_DN');
2797 }
2798 if ($mode == 1) {
2799 $dn = getDolGlobalString('LDAP_MEMBER_DN');
2800 }
2801 if ($mode == 2) {
2802 $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')];
2803 }
2804 return $dn;
2805 }
2806
2807
2808 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2809 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2815 public function _load_ldap_info()
2816 {
2817 // phpcs:enable
2818 global $conf, $langs;
2819
2820 $info = array();
2821 $socialnetworks = getArrayOfSocialNetworks();
2822 $keymodified = false;
2823
2824 // Object classes
2825 $info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
2826
2827 $this->fullname = $this->getFullName($langs);
2828
2829 // For avoid ldap error when firstname and lastname are empty
2830 if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
2831 $this->fullname = $this->company;
2832 $this->lastname = $this->company;
2833 }
2834
2835 // Possible LDAP KEY (constname => varname)
2836 $ldapkey = array(
2837 'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
2838 'LDAP_MEMBER_FIELD_NAME' => 'lastname',
2839 'LDAP_MEMBER_FIELD_LOGIN' => 'login',
2840 'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
2841 'LDAP_MEMBER_FIELD_MAIL' => 'email'
2842 );
2843
2844 // Member
2845 foreach ($ldapkey as $constname => $varname) {
2846 if (!empty($this->$varname) && getDolGlobalString($constname)) {
2847 $info[getDolGlobalString($constname)] = $this->$varname;
2848
2849 // Check if it is the LDAP key and if its value has been changed
2850 if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
2851 if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
2852 $keymodified = true; // For check if LDAP key has been modified
2853 }
2854 }
2855 }
2856 }
2857 if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
2858 $info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
2859 }
2860 if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
2861 $info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
2862 }
2863 if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
2864 $info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
2865 }
2866 if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
2867 $info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
2868 }
2869 if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
2870 $info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
2871 }
2872 if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
2873 $info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
2874 }
2875 if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
2876 $info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
2877 }
2878 foreach ($socialnetworks as $key => $value) {
2879 if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))) {
2880 $info[getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
2881 }
2882 }
2883 if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
2884 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
2885 }
2886 if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
2887 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
2888 }
2889 if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
2890 $info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
2891 }
2892 if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
2893 $info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
2894 }
2895 if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
2896 $info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
2897 }
2898 if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
2899 $info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
2900 }
2901 if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
2902 $info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
2903 }
2904 if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
2905 $info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
2906 }
2907 if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
2908 $info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
2909 }
2910
2911 // When password is modified
2912 if (!empty($this->pass)) {
2913 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2914 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
2915 }
2916 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2917 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2918 }
2919 } elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
2920 // Set LDAP password if possible
2921 // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2922 if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
2923 // Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
2924 if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
2925 if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2926 // Create OpenLDAP MD5 password from Dolibarr MD5 password
2927 // Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
2928 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
2929 }
2930 }
2931 } elseif (!empty($this->pass_indatabase)) {
2932 // Use $this->pass_indatabase value if exists
2933 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2934 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
2935 }
2936 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2937 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2938 }
2939 }
2940 }
2941
2942 // Subscriptions
2943 if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
2944 $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
2945 }
2946 if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
2947 $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
2948 }
2949 if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
2950 $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
2951 }
2952 if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
2953 $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
2954 }
2955
2956 return $info;
2957 }
2958
2959
2966 public function info($id)
2967 {
2968 $sql = 'SELECT a.rowid, a.datec as datec,';
2969 $sql .= ' a.datevalid as datev,';
2970 $sql .= ' a.tms as datem,';
2971 $sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2972 $sql .= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
2973 $sql .= ' WHERE a.rowid = '.((int) $id);
2974
2975 dol_syslog(get_class($this)."::info", LOG_DEBUG);
2976 $result = $this->db->query($sql);
2977 if ($result) {
2978 if ($this->db->num_rows($result)) {
2979 $obj = $this->db->fetch_object($result);
2980
2981 $this->id = $obj->rowid;
2982
2983 $this->user_creation_id = $obj->fk_user_author;
2984 $this->user_validation_id = $obj->fk_user_valid;
2985 $this->user_modification_id = $obj->fk_user_mod;
2986 $this->date_creation = $this->db->jdate($obj->datec);
2987 $this->date_validation = $this->db->jdate($obj->datev);
2988 $this->date_modification = $this->db->jdate($obj->datem);
2989 }
2990
2991 $this->db->free($result);
2992 } else {
2993 dol_print_error($this->db);
2994 }
2995 }
2996
3002 public function getNbOfEMailings()
3003 {
3004 $sql = "SELECT count(mc.email) as nb";
3005 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
3006 $sql .= " WHERE mc.email = '".$this->db->escape($this->email)."'";
3007 $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec success
3008
3009 $resql = $this->db->query($sql);
3010 if ($resql) {
3011 $obj = $this->db->fetch_object($resql);
3012 $nb = $obj->nb;
3013
3014 $this->db->free($resql);
3015 return $nb;
3016 } else {
3017 $this->error = $this->db->error();
3018 return -1;
3019 }
3020 }
3021
3032 public function setCategories($categories)
3033 {
3034 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
3035 return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
3036 }
3037
3046 public static function replaceThirdparty($db, $origin_id, $dest_id)
3047 {
3048 $tables = array('adherent');
3049
3050 return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
3051 }
3052
3058 public function hasDelay()
3059 {
3060 global $conf;
3061
3062 //Only valid members
3063 if ($this->statut != self::STATUS_VALIDATED) {
3064 return false;
3065 }
3066 if (!$this->datefin) {
3067 return false;
3068 }
3069
3070 $now = dol_now();
3071
3072 return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
3073 }
3074
3075
3084 public function sendReminderForExpiredSubscription($daysbeforeendlist = '10', $fk_adherent_type = 0)
3085 {
3086 global $conf, $langs, $mysoc, $user;
3087
3088 $error = 0;
3089 $this->output = '';
3090 $this->error = '';
3091
3092 $blockingerrormsg = '';
3093
3094 if (!isModEnabled('member')) { // Should not happen. If module disabled, cron job should not be visible.
3095 $langs->load("agenda");
3096 $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3097 return 0;
3098 }
3099 if (!getDolGlobalString('MEMBER_REMINDER_EMAIL')) {
3100 $langs->load("agenda");
3101 $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3102 return 0;
3103 }
3104
3105 $now = dol_now();
3106 $nbok = 0;
3107 $nbko = 0;
3108
3109 $listofmembersok = array();
3110 $listofmembersko = array();
3111
3112 $arraydaysbeforeend = explode(';', $daysbeforeendlist);
3113 foreach ($arraydaysbeforeend as $daysbeforeend) { // Loop on each delay
3114 dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
3115
3116 if (!is_numeric($daysbeforeend)) {
3117 $blockingerrormsg = "Value for delta is not a numeric value";
3118 $nbko++;
3119 break;
3120 }
3121
3122 $tmp = dol_getdate($now);
3123 $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
3124 $datetosearchforend = dol_time_plus_duree(dol_mktime(23, 59, 59, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
3125
3126 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
3127 $sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
3128 $sql .= " AND statut = 1";
3129 $sql .= " AND datefin >= '".$this->db->idate($datetosearchfor)."'";
3130 $sql .= " AND datefin <= '".$this->db->idate($datetosearchforend)."'";
3131 if ((int) $fk_adherent_type > 0) {
3132 $sql .= " AND fk_adherent_type = ".((int) $fk_adherent_type);
3133 }
3134 //$sql .= " LIMIT 10000";
3135
3136 $resql = $this->db->query($sql);
3137 if ($resql) {
3138 $num_rows = $this->db->num_rows($resql);
3139
3140 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
3141 $adherent = new Adherent($this->db);
3142 $formmail = new FormMail($this->db);
3143
3144 $i = 0;
3145 while ($i < $num_rows) {
3146 $obj = $this->db->fetch_object($resql);
3147
3148 $adherent->fetch($obj->rowid, '', 0, '', true, true);
3149
3150 if (empty($adherent->email)) {
3151 $nbko++;
3152 $listofmembersko[$adherent->id] = $adherent->id;
3153 } else {
3154 $thirdpartyres = $adherent->fetch_thirdparty();
3155 if ($thirdpartyres === -1) {
3156 $languagecodeformember = $mysoc->default_lang;
3157 } else {
3158 // 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.
3159 $languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : $adherent->thirdparty->country_code);
3160 $languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
3161 }
3162
3163 // Send reminder email
3164 $outputlangs = new Translate('', $conf);
3165 $outputlangs->setDefaultLang($languagecodeformember);
3166 $outputlangs->loadLangs(array("main", "members"));
3167 dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
3168
3169 $arraydefaultmessage = null;
3170 $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
3171
3172 if (!empty($labeltouse)) {
3173 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
3174 }
3175
3176 if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
3177 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
3178 //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
3179 complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
3180
3181 $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
3182 $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
3183 $from = getDolGlobalString('ADHERENT_MAIL_FROM');
3184 $to = $adherent->email;
3185 $cc = getDolGlobalString('ADHERENT_CC_MAIL_FROM');
3186
3187 $trackid = 'mem'.$adherent->id;
3188 $moreinheader = 'X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
3189
3190 include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
3191 $cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), $cc, '', 0, 1, '', '', $trackid, $moreinheader);
3192 $result = $cmail->sendfile();
3193 if (!$result) {
3194 $error++;
3195 $this->error .= $cmail->error.' ';
3196 if (!is_null($cmail->errors)) {
3197 $this->errors += $cmail->errors;
3198 }
3199 $nbko++;
3200 $listofmembersko[$adherent->id] = $adherent->id;
3201 } else {
3202 $nbok++;
3203 $listofmembersok[$adherent->id] = $adherent->id;
3204
3205 $message = $msg;
3206 $sendto = $to;
3207 $sendtocc = '';
3208 $sendtobcc = '';
3209 $actioncode = 'EMAIL';
3210 $extraparams = '';
3211
3212 $actionmsg = '';
3213 $actionmsg2 = $langs->transnoentities('MailSentByTo', CMailFile::getValidAddress($from, 4, 0, 1), CMailFile::getValidAddress($sendto, 4, 0, 1));
3214 if ($message) {
3215 $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
3216 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
3217 if ($sendtocc) {
3218 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".dol_escape_htmltag($sendtocc));
3219 }
3220 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject);
3221 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":");
3222 $actionmsg = dol_concatdesc($actionmsg, $message);
3223 }
3224
3225 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
3226
3227 // Insert record of emails sent
3228 $actioncomm = new ActionComm($this->db);
3229
3230 $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
3231 $actioncomm->code = 'AC_'.$actioncode;
3232 $actioncomm->label = $actionmsg2;
3233 $actioncomm->note_private = $actionmsg;
3234 $actioncomm->fk_project = 0;
3235 $actioncomm->datep = $now;
3236 $actioncomm->datef = $now;
3237 $actioncomm->percentage = -1; // Not applicable
3238 $actioncomm->socid = $adherent->thirdparty->id;
3239 $actioncomm->contact_id = 0;
3240 $actioncomm->authorid = $user->id; // User saving action
3241 $actioncomm->userownerid = $user->id; // Owner of action
3242 // Fields when action is en email (content should be added into note)
3243 $actioncomm->email_msgid = $cmail->msgid;
3244 $actioncomm->email_from = $from;
3245 $actioncomm->email_sender = '';
3246 $actioncomm->email_to = $to;
3247 $actioncomm->email_tocc = $sendtocc;
3248 $actioncomm->email_tobcc = $sendtobcc;
3249 $actioncomm->email_subject = $subject;
3250 $actioncomm->errors_to = '';
3251
3252 $actioncomm->fk_element = $adherent->id;
3253 $actioncomm->elementid = $adherent->id;
3254 $actioncomm->elementtype = $adherent->element;
3255
3256 $actioncomm->extraparams = $extraparams;
3257
3258 $actioncomm->create($user);
3259 }
3260 } else {
3261 //$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
3262
3263 $error++;
3264 $this->error .= "Can't find email template with label=".$labeltouse.", to use for the reminding email ";
3265
3266 $nbko++;
3267 $listofmembersko[$adherent->id] = $adherent->id;
3268
3269 break;
3270 }
3271 }
3272
3273 $i++;
3274 }
3275 } else {
3276 $this->error = $this->db->lasterror();
3277 return 1;
3278 }
3279 }
3280
3281 if ($blockingerrormsg) {
3282 $this->error = $blockingerrormsg;
3283 return 1;
3284 } else {
3285 $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
3286 $this->output .= ' Send email successfully to '.$nbok.' members';
3287 if (is_array($listofmembersok)) {
3288 $listofids = '';
3289 $i = 0;
3290 foreach ($listofmembersok as $idmember) {
3291 if ($i > 100) {
3292 $listofids .= ', ...';
3293 break;
3294 }
3295 if (empty($listofids)) {
3296 $listofids .= ' [';
3297 } else {
3298 $listofids .= ', ';
3299 }
3300 $listofids .= $idmember;
3301 $i++;
3302 }
3303 if ($listofids) {
3304 $listofids .= ']';
3305 }
3306
3307 $this->output .= ($listofids ? ' ids='.$listofids : '');
3308 }
3309 if ($nbko) {
3310 $this->output .= ' - Canceled for '.$nbko.' member (no email or email sending error)';
3311 if (is_array($listofmembersko)) {
3312 $listofids = '';
3313 $i = 0;
3314 foreach ($listofmembersko as $idmember) {
3315 if ($i > 100) {
3316 $listofids .= ', ...';
3317 break;
3318 }
3319 if (empty($listofids)) {
3320 $listofids .= ' [';
3321 } else {
3322 $listofids .= ', ';
3323 }
3324 $listofids .= $idmember;
3325 $i++;
3326 }
3327 if ($listofids) {
3328 $listofids .= ']';
3329 }
3330 $this->output .= ($listofids ? ' ids='.$listofids : '');
3331 }
3332 }
3333 }
3334
3335 return $nbko;
3336 }
3337
3345 public function getKanbanView($option = '', $arraydata = null)
3346 {
3347 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
3348
3349 $return = '<div class="box-flex-item box-flex-grow-zero">';
3350 $return .= '<div class="info-box info-box-sm">';
3351 $return .= '<span class="info-box-icon bg-infobox-action">';
3352 if (property_exists($this, 'photo') || !empty($this->photo)) {
3353 $return .= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photowithmargin photologintooltip', 'small', 0, 1);
3354 } else {
3355 $return .= img_picto('', 'user');
3356 }
3357 $return .= '</span>';
3358 $return .= '<div class="info-box-content">';
3359 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
3360 if ($selected >= 0) {
3361 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
3362 }
3363 $return .= '<br><span class="info-box-label paddingright">'.$this->getmorphylib('', 2).'</span>';
3364 $return .= '<span class="info-box-label opacitymedium">'.$this->type.'</span>';
3365
3366 if (method_exists($this, 'getLibStatut')) {
3367 $return .= '<br><div class="info-box-status paddingtop">';
3368 $return .= $this->LibStatut($this->status, $this->need_subscription, $this->datefin, 5);
3369 $return .= '</div>';
3370 }
3371 $return .= '</div>';
3372 $return .= '</div>';
3373 $return .= '</div>';
3374 return $return;
3375 }
3376}
$object ref
Definition info.php:89
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.
_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.
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.
$fields
'type' field format: 'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortf...
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
const STATUS_DRAFT
Draft status.
const STATUS_RESILIATED
Resiliated (membership end and was not renew)
sendReminderForExpiredSubscription($daysbeforeendlist='10', $fk_adherent_type=0)
Send reminders by emails before subscription end CAN BE A CRON TASK.
fetch_login($login)
Method to load member from its login.
_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 clickable name (with picto eventually)
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
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.
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.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
getFullName($langs, $option=0, $nameorder=-1, $maxlen=0)
Return full name (civility+' '+name+' '+lastname)
setUpperOrLowerCase()
Set to upper or ucwords/lower if needed.
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:125
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as p label as s rowid as s nom as s email
Sender: Who sends the email ("Sender" has sent emails on behalf of "From").
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...
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
getLanguageCodeFromCountryCode($countrycode)
Return default language from country code.
setEntity($currentobject)
Set entity id to use when to create an object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
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.
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 '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
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_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.
yn($yesno, $format=1, $color=0)
Return yes or no in current language.
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 a Dolibarr global constant string value.
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 refaddress div address
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:150
getRandomPassword($generic=false, $replaceambiguouschars=null, $length=32)
Return a generated password using default module.
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.
dolGetLdapPasswordHash($password, $type='md5')
Returns a specific ldap hash of a password.