dolibarr 22.0.5
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-2025 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-2025 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
101 public $civility_id;
102
106 public $civility_code;
107
111 public $civility;
112
118 public $societe;
119
123 public $company;
124
130 public $fk_soc;
131
135 public $socid;
136
140 public $socialnetworks;
141
145 public $phone;
146
150 public $phone_perso;
151
155 public $phone_pro;
156
160 public $phone_mobile;
161
165 public $fax;
166
170 public $poste;
171
175 public $morphy;
176
180 public $public;
181
186 public $default_lang;
187
191 public $photo;
192
198 public $datec;
199
205 public $datem;
206
210 public $datevalid;
211
215 public $gender;
216
220 public $birth;
221
225 public $typeid;
226
230 public $type;
231
235 public $need_subscription;
236
240 public $user_id;
241
245 public $user_login;
246
250 public $datefin;
251
252
253 // Fields loaded by fetch_subscriptions() from member table
254
258 public $first_subscription_date;
259
263 public $first_subscription_date_start;
264
268 public $first_subscription_date_end;
269
273 public $first_subscription_amount;
274
278 public $last_subscription_date;
279
283 public $last_subscription_date_start;
284
288 public $last_subscription_date_end;
289
293 public $last_subscription_amount;
294
298 public $subscriptions = array();
299
303 public $ip;
304
305 // Fields loaded by fetchPartnerships() from partnership table
306
310 public $partnerships = array();
311
315 public $invoice;
316
317
359 public $fields = array(
360 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
361 'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
362 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 15, 'index' => 1),
363 'ref_ext' => array('type' => 'varchar(128)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 20),
364 'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
365 'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
366 'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
367 'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => 1, 'position' => 40),
368 'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => 3, 'position' => 45),
369 'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => 3, 'position' => 50),
370 'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
371 'fk_adherent_type' => array('type' => 'integer', 'label' => 'MemberType', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
372 'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
373 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
374 'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
375 'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
376 'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
377 'state_id' => array('type' => 'integer', 'label' => 'State', 'enabled' => 1, 'visible' => -1, 'position' => 90),
378 'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
379 'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
380 'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
381 'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
382 'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
383 'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
384 'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => 3, 'position' => 128),
385 'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
386 'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
387 'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
388 'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 145),
389 'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
390 'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
391 'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
392 'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
393 'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
394 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
395 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
396 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserCreation', 'enabled' => 1, 'visible' => 3, 'position' => 180),
397 'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModification', 'enabled' => 1, 'visible' => 3, 'position' => 185),
398 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => 3, 'position' => 190),
399 'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => 0, 'position' => 195),
400 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
401 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805),
402 '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'))
403 );
404
408 const STATUS_DRAFT = -1;
420 const STATUS_EXCLUDED = -2;
421
422
428 public function __construct($db)
429 {
430 $this->db = $db;
431 $this->statut = self::STATUS_DRAFT;
432 $this->status = self::STATUS_DRAFT;
433 // l'adherent n'est pas public par default
434 $this->public = 0;
435 $this->ismultientitymanaged = 1;
436 $this->isextrafieldmanaged = 1;
437 // les champs optionnels sont vides
438 $this->array_options = array();
439
440 $this->fields['ref_ext']['visible'] = getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT');
441 }
442
443
444 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
463 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 = '')
464 {
465 // phpcs:enable
466 dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
467
468 return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
469 }
470
488 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 = '')
489 {
490 global $conf, $langs;
491
492 // Detect if message is HTML
493 if ($msgishtml == -1) {
494 $msgishtml = 0;
495 if (dol_textishtml($text, 0)) {
496 $msgishtml = 1;
497 }
498 }
499
500 dol_syslog('sendEmail msgishtml='.$msgishtml);
501
502 $texttosend = $this->makeSubstitution($text);
503 $subjecttosend = $this->makeSubstitution($subject);
504 if ($msgishtml) {
505 $texttosend = dol_htmlentitiesbr($texttosend);
506 }
507
508 // Send mail confirmation
509 $from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
510
511 $trackid = 'mem'.$this->id;
512
513 // Send email (substitutionarray must be done just before this)
514 include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
515 $mailfile = new CMailFile($subjecttosend, (string) $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
516 if ($mailfile->sendfile()) {
517 return 1;
518 } else {
519 $this->error = $langs->trans("ErrorFailedToSendMail", $from, (string) $this->email).'. '.$mailfile->error;
520 return -1;
521 }
522 }
523
524
531 public function makeSubstitution($text)
532 {
533 global $langs;
534
535 $birthday = dol_print_date($this->birth, 'day');
536 $photo = isset($this->photo) ? $this->photo : '';
537 $login = isset($this->login) ? $this->login : '';
538 $type = isset($this->type) ? $this->type : '';
539 $pass = isset($this->pass) ? $this->pass : '';
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").": ".$login."\n";
565 $infos .= $langs->transnoentities("Password").": ".$pass."\n";
566 }
567 $infos .= $langs->transnoentities("Birthday").": ".$birthday."\n";
568 $infos .= $langs->transnoentities("Photo").": ".$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((string) $this->company) : ($this->company ? $this->company : ''),
581 '__ADDRESS__' => $msgishtml ? dol_htmlentitiesbr((string) $this->address) : ($this->address ? $this->address : ''),
582 '__ZIP__' => $msgishtml ? dol_htmlentitiesbr((string) $this->zip) : ($this->zip ? $this->zip : ''),
583 '__TOWN__' => $msgishtml ? dol_htmlentitiesbr((string) $this->town) : ($this->town ? $this->town : ''),
584 '__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''),
585 '__EMAIL__' => $msgishtml ? dol_htmlentitiesbr((string) $this->email) : ($this->email ? $this->email : ''),
586 '__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''),
587 '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($photo) : $photo,
588 '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($login) : $login,
589 '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($pass) : $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($type) : $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((string) $this->email)) {
675 $langs->load("errors");
676 $this->error = $langs->trans("ErrorBadEMail", (string) $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 if (empty($this->country_id) && !empty($this->country_code)) {
805 $country_id = getCountry($this->country_code, '3');
806 $this->country_id = is_int($country_id) ? $country_id : 0;
807 }
808
809 $nbrowsaffected = 0;
810 $error = 0;
811
812 dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
813
814 // Clean parameters
815 $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
816 $this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
817 $this->gender = trim($this->gender);
818 // $this->address = ($this->address ? $this->address : $this->address);
819 // $this->zip = ($this->zip ? $this->zip : $this->zip);
820 // $this->town = ($this->town ? $this->town : $this->town);
821 // $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
822 // $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id);
823 // $this->note_public = ($this->note_public ? $this->note_public : $this->note_public);
824 // $this->note_private = ($this->note_private ? $this->note_private : $this->note_private);
825 $this->url = $this->url ? clean_url($this->url, 0) : '';
826 $this->setUpperOrLowerCase();
827 // Check parameters
828 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail((string) $this->email)) {
829 $langs->load("errors");
830 $this->error = $langs->trans("ErrorBadEMail", (string) $this->email);
831 return -1;
832 }
833
834 $this->db->begin();
835
836 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
837 $sql .= " ref = '".$this->db->escape($this->ref)."'";
838 $sql .= ", civility = ".($this->civility_id ? "'".$this->db->escape($this->civility_id)."'" : "null");
839 $sql .= ", firstname = ".($this->firstname ? "'".$this->db->escape($this->firstname)."'" : "null");
840 $sql .= ", lastname = ".($this->lastname ? "'".$this->db->escape($this->lastname)."'" : "null");
841 $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
842 $sql .= ", login = ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
843 $sql .= ", societe = ".($this->company ? "'".$this->db->escape($this->company)."'" : ($this->societe ? "'".$this->db->escape($this->societe)."'" : "null"));
844 if ($this->socid) {
845 $sql .= ", fk_soc = ".($this->socid > 0 ? (int) $this->socid : "null"); // Must be modified only when creating from a third-party
846 }
847 $sql .= ", address = ".($this->address ? "'".$this->db->escape($this->address)."'" : "null");
848 $sql .= ", zip = ".($this->zip ? "'".$this->db->escape($this->zip)."'" : "null");
849 $sql .= ", town = ".($this->town ? "'".$this->db->escape($this->town)."'" : "null");
850 $sql .= ", country = ".($this->country_id > 0 ? (int) $this->country_id : "null");
851 $sql .= ", state_id = ".($this->state_id > 0 ? (int) $this->state_id : "null");
852 $sql .= ", email = '".$this->db->escape((string) $this->email)."'";
853 $sql .= ", url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
854 $sql .= ", socialnetworks = ".($this->socialnetworks ? "'".$this->db->escape(json_encode($this->socialnetworks))."'" : "null");
855 $sql .= ", phone = ".($this->phone ? "'".$this->db->escape($this->phone)."'" : "null");
856 $sql .= ", phone_perso = ".($this->phone_perso ? "'".$this->db->escape($this->phone_perso)."'" : "null");
857 $sql .= ", phone_mobile = ".($this->phone_mobile ? "'".$this->db->escape($this->phone_mobile)."'" : "null");
858 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
859 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
860 $sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
861 $sql .= ", public = ".(int) $this->public;
862 $sql .= ", statut = ".(int) $this->statut;
863 $sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
864 $sql .= ", fk_adherent_type = ".(int) $this->typeid;
865 $sql .= ", morphy = '".$this->db->escape($this->morphy)."'";
866 $sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null");
867
868 if ($this->datefin) {
869 $sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
870 }
871 if ($this->datevalid) {
872 $sql .= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
873 }
874 $sql .= ", fk_user_mod = ".($user->id > 0 ? $user->id : 'null'); // Can be null because member can be create by a guest
875 $sql .= " WHERE rowid = ".((int) $this->id);
876
877 // If we change the type of membership, we set also label of new type..
878 '@phan-var-force Adherent $oldcopy';
879 if (!empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid) {
880 $sql2 = "SELECT libelle as label";
881 $sql2 .= " FROM ".MAIN_DB_PREFIX."adherent_type";
882 $sql2 .= " WHERE rowid = ".((int) $this->typeid);
883 $resql2 = $this->db->query($sql2);
884 if ($resql2) {
885 while ($obj = $this->db->fetch_object($resql2)) {
886 $this->type = $obj->label;
887 }
888 }
889 }
890
891 dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
892 $resql = $this->db->query($sql);
893 if ($resql) {
894 unset($this->country_code);
895 unset($this->country);
896 unset($this->state_code);
897 unset($this->state);
898
899 $nbrowsaffected += $this->db->affected_rows($resql);
900
901 $action = 'update';
902
903 // Actions on extra fields
904 if (!$error) {
905 $result = $this->insertExtraFields();
906 if ($result < 0) {
907 $error++;
908 }
909 }
910
911 // Update password
912 if (!$error && $this->pass) {
913 dol_syslog(get_class($this)."::update update password");
914 if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) {
915 $isencrypted = getDolGlobalString('DATABASE_PWD_ENCRYPTED') ? 1 : 0;
916
917 // If password to set differs from the one found into database
918 $result = $this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
919 if (!$nbrowsaffected) {
920 $nbrowsaffected++;
921 }
922 }
923 }
924
925 // Remove links to user and replace with new one
926 if (!$error) {
927 dol_syslog(get_class($this)."::update update link to user");
928 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
929 dol_syslog(get_class($this)."::update", LOG_DEBUG);
930 $resql = $this->db->query($sql);
931 if (!$resql) {
932 $this->error = $this->db->error();
933 $this->db->rollback();
934 return -5;
935 }
936 // If there is a user linked to this member
937 if ($this->user_id > 0) {
938 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id)." WHERE rowid = ".((int) $this->user_id);
939 dol_syslog(get_class($this)."::update", LOG_DEBUG);
940 $resql = $this->db->query($sql);
941 if (!$resql) {
942 $this->error = $this->db->error();
943 $this->db->rollback();
944 return -5;
945 }
946 }
947 }
948
949 if (!$error && $nbrowsaffected) { // If something has change in main data
950 // Update information on linked user if it is an update
951 if (!$error && $this->user_id > 0 && !$nosyncuser) {
952 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
953
954 dol_syslog(get_class($this)."::update update linked user");
955
956 $luser = new User($this->db);
957 $result = $luser->fetch($this->user_id);
958
959 if ($result >= 0) {
960 // 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.
961 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
962 $luser->login = $this->login;
963 }
964
965 $luser->ref = $this->ref;
966 $luser->civility_id = $this->civility_id;
967 $luser->firstname = $this->firstname;
968 $luser->lastname = $this->lastname;
969 $luser->gender = $this->gender;
970 $luser->pass = isset($this->pass) ? $this->pass : '';
971 //$luser->socid=$this->fk_soc; // We do not enable this. This may transform a user into an external user.
972
973 $luser->birth = $this->birth;
974
975 $luser->address = $this->address;
976 $luser->zip = $this->zip;
977 $luser->town = $this->town;
978 $luser->country_id = $this->country_id;
979 $luser->state_id = $this->state_id;
980
981 $luser->email = $this->email;
982 $luser->socialnetworks = $this->socialnetworks;
983 $luser->office_phone = $this->phone;
984 $luser->user_mobile = $this->phone_mobile;
985
986 $luser->lang = $this->default_lang;
987
988 $luser->fk_member = $this->id;
989
990 $result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
991 if ($result < 0) {
992 $this->error = $luser->error;
993 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
994 $error++;
995 }
996 } else {
997 $this->error = $luser->error;
998 $error++;
999 }
1000 }
1001
1002 // Update information on linked thirdparty if it is an update
1003 if (!$error && $this->fk_soc > 0 && !$nosyncthirdparty) {
1004 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1005
1006 dol_syslog(get_class($this)."::update update linked thirdparty");
1007
1008 // This member is linked with a thirdparty, so we also update thirdparty information
1009 // if this is an update.
1010 $lthirdparty = new Societe($this->db);
1011 $result = $lthirdparty->fetch($this->fk_soc);
1012
1013 if ($result > 0) {
1014 $lthirdparty->address = $this->address;
1015 $lthirdparty->zip = $this->zip;
1016 $lthirdparty->town = $this->town;
1017 $lthirdparty->email = $this->email;
1018 $lthirdparty->socialnetworks = $this->socialnetworks;
1019 $lthirdparty->phone = $this->phone;
1020 $lthirdparty->state_id = $this->state_id;
1021 $lthirdparty->country_id = $this->country_id;
1022 //$lthirdparty->phone_mobile=$this->phone_mobile;
1023 $lthirdparty->default_lang = $this->default_lang;
1024
1025 $result = $lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
1026
1027 if ($result < 0) {
1028 $this->error = $lthirdparty->error;
1029 $this->errors = $lthirdparty->errors;
1030 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
1031 $error++;
1032 }
1033 } elseif ($result < 0) {
1034 $this->error = $lthirdparty->error;
1035 $error++;
1036 }
1037 }
1038 }
1039
1040 if (!$error && !$notrigger) {
1041 // Call trigger
1042 $result = $this->call_trigger('MEMBER_MODIFY', $user);
1043 if ($result < 0) {
1044 $error++;
1045 }
1046 // End call triggers
1047 }
1048
1049 if (!$error) {
1050 $this->db->commit();
1051 return $nbrowsaffected;
1052 } else {
1053 $this->db->rollback();
1054 return -1;
1055 }
1056 } else {
1057 $this->db->rollback();
1058 $this->error = $this->db->lasterror();
1059 return -2;
1060 }
1061 }
1062
1063
1064 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1072 public function update_end_date($user)
1073 {
1074 // phpcs:enable
1075 $this->db->begin();
1076
1077 // Search for last subscription id and end date
1078 $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
1079 $sql .= " FROM ".MAIN_DB_PREFIX."subscription";
1080 $sql .= " WHERE fk_adherent = ".((int) $this->id);
1081 $sql .= " ORDER by dateadh DESC"; // Sort by start subscription date
1082
1083 dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1084 $resql = $this->db->query($sql);
1085 if ($resql) {
1086 // The last subscription is the one with the latest start date (first record), but the end date of the member is
1087 // the latest end date of all its subscriptions: a short subscription that starts after a longer one must not
1088 // shorten the membership. There is no record at all when the last subscription of the member was deleted.
1089 $dateop = '';
1090 $datedeb = '';
1091 $datefin = '';
1092 $dateendmember = '';
1093 $i = 0;
1094 while ($obj = $this->db->fetch_object($resql)) {
1095 $dateendsubscription = $this->db->jdate($obj->datefin);
1096 if ($i == 0) {
1097 $dateop = $this->db->jdate($obj->dateop);
1098 $datedeb = $this->db->jdate($obj->datedeb);
1099 $datefin = $dateendsubscription;
1100 }
1101 if ($dateendsubscription != '' && ($dateendmember == '' || $dateendsubscription > $dateendmember)) {
1102 $dateendmember = $dateendsubscription;
1103 }
1104 $i++;
1105 }
1106
1107 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1108 $sql .= " datefin=".($dateendmember != '' ? "'".$this->db->idate($dateendmember)."'" : "null");
1109 $sql .= " WHERE rowid = ".((int) $this->id);
1110
1111 dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1112 $resql = $this->db->query($sql);
1113 if ($resql) {
1114 $this->last_subscription_date = $dateop;
1115 $this->last_subscription_date_start = $datedeb;
1116 $this->last_subscription_date_end = $datefin;
1117 $this->datefin = $dateendmember;
1118 $this->db->commit();
1119 return 1;
1120 } else {
1121 $this->db->rollback();
1122 return -1;
1123 }
1124 } else {
1125 $this->error = $this->db->lasterror();
1126 $this->db->rollback();
1127 return -1;
1128 }
1129 }
1130
1138 public function delete($user, $notrigger = 0)
1139 {
1140 $result = 0;
1141 $error = 0;
1142 $errorflag = 0;
1143
1144 // Check parameters
1145 $rowid = $this->id;
1146
1147 $this->db->begin();
1148
1149 if (!$error && !$notrigger) {
1150 // Call trigger
1151 $result = $this->call_trigger('MEMBER_DELETE', $user);
1152 if ($result < 0) {
1153 $error++;
1154 }
1155 // End call triggers
1156 }
1157
1158 // Remove category
1159 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".((int) $rowid);
1160 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1161 $resql = $this->db->query($sql);
1162 if (!$resql) {
1163 $error++;
1164 $this->error .= $this->db->lasterror();
1165 $errorflag = -1;
1166 }
1167
1168 // Remove subscription
1169 if (!$error) {
1170 $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".((int) $rowid);
1171 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1172 $resql = $this->db->query($sql);
1173 if (!$resql) {
1174 $error++;
1175 $this->error .= $this->db->lasterror();
1176 $errorflag = -2;
1177 }
1178 }
1179
1180 // Remove linked user
1181 if (!$error) {
1182 $ret = $this->setUserId(0);
1183 if ($ret < 0) {
1184 $error++;
1185 $this->error .= $this->db->lasterror();
1186 $errorflag = -3;
1187 }
1188 }
1189
1190 // Removed extrafields
1191 if (!$error) {
1192 $result = $this->deleteExtraFields();
1193 if ($result < 0) {
1194 $error++;
1195 $errorflag = -4;
1196 dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
1197 }
1198 }
1199
1200 // Remove adherent
1201 if (!$error) {
1202 $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".((int) $rowid);
1203 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1204 $resql = $this->db->query($sql);
1205 if (!$resql) {
1206 $error++;
1207 $this->error .= $this->db->lasterror();
1208 $errorflag = -5;
1209 }
1210 }
1211
1212 if (!$error) {
1213 $this->db->commit();
1214 return 1;
1215 } else {
1216 $this->db->rollback();
1217 return $errorflag;
1218 }
1219 }
1220
1221
1232 public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
1233 {
1234 global $conf, $langs;
1235
1236 $error = 0;
1237
1238 dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." isencrypted=".$isencrypted);
1239
1240 // If new password not provided, we generate one
1241 if (!$password) {
1242 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
1243 $password = getRandomPassword(false);
1244 }
1245
1246 // Crypt password
1247 $password_crypted = dol_hash($password);
1248
1249 $password_indatabase = '';
1250 if (!$isencrypted) {
1251 $password_indatabase = $password;
1252 }
1253
1254 $this->db->begin();
1255
1256 // Mise a jour
1257 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
1258 $sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
1259 if ($isencrypted) {
1260 $sql .= ", pass = null";
1261 } else {
1262 $sql .= ", pass = '".$this->db->escape($password_indatabase)."'";
1263 }
1264 $sql .= " WHERE rowid = ".((int) $this->id);
1265
1266 //dol_syslog("Adherent::Password sql=hidden");
1267 dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1268 $result = $this->db->query($sql);
1269 if ($result) {
1270 $nbaffectedrows = $this->db->affected_rows($result);
1271
1272 if ($nbaffectedrows) {
1273 $this->pass = $password;
1274 $this->pass_indatabase = $password_indatabase;
1275 $this->pass_indatabase_crypted = $password_crypted;
1276
1277 if ($this->user_id && !$nosyncuser) {
1278 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1279
1280 // This member is linked with a user, so we also update users information
1281 // if this is an update.
1282 $luser = new User($this->db);
1283 $result = $luser->fetch($this->user_id);
1284
1285 if ($result >= 0) {
1286 $result = $luser->setPassword($user, $this->pass, 0, 0, 1);
1287 if (is_int($result) && $result < 0) {
1288 $this->error = $luser->error;
1289 dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR);
1290 $error++;
1291 }
1292 } else {
1293 $this->error = $luser->error;
1294 $error++;
1295 }
1296 }
1297
1298 if (!$error && !$notrigger) {
1299 // Call trigger
1300 $result = $this->call_trigger('MEMBER_NEW_PASSWORD', $user);
1301 if ($result < 0) {
1302 $error++;
1303 $this->db->rollback();
1304 return -1;
1305 }
1306 // End call triggers
1307 }
1308
1309 $this->db->commit();
1310 return $this->pass;
1311 } else {
1312 $this->db->rollback();
1313 return 0;
1314 }
1315 } else {
1316 $this->db->rollback();
1317 dol_print_error($this->db);
1318 return -1;
1319 }
1320 }
1321
1322
1329 public function setUserId($userid)
1330 {
1331 global $conf, $langs;
1332
1333 $this->db->begin();
1334
1335 // If user is linked to this member, remove old link to this member
1336 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
1337 dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1338 $resql = $this->db->query($sql);
1339 if (!$resql) {
1340 $this->error = $this->db->error();
1341 $this->db->rollback();
1342 return -1;
1343 }
1344
1345 // Set link to user
1346 if ($userid > 0) {
1347 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id);
1348 $sql .= " WHERE rowid = ".((int) $userid);
1349 dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1350 $resql = $this->db->query($sql);
1351 if (!$resql) {
1352 $this->error = $this->db->error();
1353 $this->db->rollback();
1354 return -2;
1355 }
1356 }
1357
1358 $this->db->commit();
1359
1360 return 1;
1361 }
1362
1363
1370 public function setThirdPartyId($thirdpartyid)
1371 {
1372 global $conf, $langs;
1373
1374 $this->db->begin();
1375
1376 // Remove link to third party onto any other members
1377 if ($thirdpartyid > 0) {
1378 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
1379 $sql .= " WHERE fk_soc = ".((int) $thirdpartyid);
1380 $sql .= " AND entity = ".$conf->entity;
1381 dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1382 $resql = $this->db->query($sql);
1383 }
1384
1385 // Add link to third party for current member
1386 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid > 0 ? (int) $thirdpartyid : 'null');
1387 $sql .= " WHERE rowid = ".((int) $this->id);
1388
1389 dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1390 $resql = $this->db->query($sql);
1391 if ($resql) {
1392 $this->db->commit();
1393 return 1;
1394 } else {
1395 $this->error = $this->db->error();
1396 $this->db->rollback();
1397 return -1;
1398 }
1399 }
1400
1401
1402 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1409 public function fetch_login($login)
1410 {
1411 // phpcs:enable
1412 global $conf;
1413
1414 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1415 $sql .= " WHERE login='".$this->db->escape($login)."'";
1416 $sql .= " AND entity = ".$conf->entity;
1417
1418 $resql = $this->db->query($sql);
1419 if ($resql) {
1420 if ($this->db->num_rows($resql)) {
1421 $obj = $this->db->fetch_object($resql);
1422 $this->fetch($obj->rowid);
1423 }
1424 } else {
1425 dol_print_error($this->db);
1426 }
1427 }
1428
1429 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1437 public function fetch_name($firstname, $lastname)
1438 {
1439 // phpcs:enable
1440 global $conf;
1441
1442 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1443 $sql .= " WHERE firstname='".$this->db->escape($firstname)."'";
1444 $sql .= " AND lastname='".$this->db->escape($lastname)."'";
1445 $sql .= " AND entity = ".$conf->entity;
1446
1447 $resql = $this->db->query($sql);
1448 if ($resql) {
1449 if ($this->db->num_rows($resql)) {
1450 $obj = $this->db->fetch_object($resql);
1451 $this->fetch($obj->rowid);
1452 }
1453 } else {
1454 dol_print_error($this->db);
1455 }
1456 }
1457
1469 public function fetch($rowid, $ref = '', $fk_soc = 0, $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
1470 {
1471 global $langs;
1472
1473 $sql = "SELECT d.rowid, d.ref, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname,";
1474 $sql .= " d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1475 $sql .= " d.note_public,";
1476 $sql .= " d.email, d.url, d.socialnetworks, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1477 $sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1478 $sql .= " d.datec as datec,";
1479 $sql .= " d.tms as datem,";
1480 $sql .= " d.datefin as datefin, d.default_lang,";
1481 $sql .= " d.birth as birthday,";
1482 $sql .= " d.datevalid as datev,";
1483 $sql .= " d.country,";
1484 $sql .= " d.state_id,";
1485 $sql .= " d.model_pdf,";
1486 $sql .= " c.rowid as country_id, c.code as country_code, c.label as country,";
1487 $sql .= " dep.nom as state, dep.code_departement as state_code,";
1488 $sql .= " t.libelle as type, t.subscription as subscription,";
1489 $sql .= " u.rowid as user_id, u.login as user_login";
1490 $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
1491 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
1492 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
1493 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
1494 $sql .= " WHERE d.fk_adherent_type = t.rowid";
1495 if ($rowid) {
1496 $sql .= " AND d.rowid=".((int) $rowid);
1497 } elseif ($ref || $fk_soc) {
1498 $sql .= " AND d.entity IN (".getEntity('adherent').")";
1499 if ($ref) {
1500 $sql .= " AND d.ref='".$this->db->escape($ref)."'";
1501 } elseif ($fk_soc > 0) {
1502 $sql .= " AND d.fk_soc=".((int) $fk_soc);
1503 }
1504 } elseif ($ref_ext) {
1505 $sql .= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
1506 }
1507
1508 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1509 $resql = $this->db->query($sql);
1510 if ($resql) {
1511 if ($this->db->num_rows($resql)) {
1512 $obj = $this->db->fetch_object($resql);
1513
1514 $this->entity = $obj->entity;
1515 $this->id = $obj->rowid;
1516 $this->ref = $obj->ref;
1517 $this->ref_ext = $obj->ref_ext;
1518
1519 $this->civility_id = $obj->civility_code; // Bad. Kept for backward compatibility
1520 $this->civility_code = $obj->civility_code;
1521 $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : '';
1522
1523 $this->firstname = $obj->firstname;
1524 $this->lastname = $obj->lastname;
1525 $this->gender = $obj->gender;
1526 $this->login = $obj->login;
1527 $this->societe = $obj->company;
1528 $this->company = $obj->company;
1529 $this->socid = $obj->fk_soc;
1530 $this->fk_soc = $obj->fk_soc; // For backward compatibility
1531 $this->address = $obj->address;
1532 $this->zip = $obj->zip;
1533 $this->town = $obj->town;
1534
1535 $this->pass = $obj->pass;
1536 $this->pass_indatabase = $obj->pass;
1537 $this->pass_indatabase_crypted = $obj->pass_crypted;
1538
1539 $this->state_id = $obj->state_id;
1540 $this->state_code = $obj->state_id ? $obj->state_code : '';
1541 $this->state = $obj->state_id ? $obj->state : '';
1542
1543 $this->country_id = $obj->country_id;
1544 $this->country_code = $obj->country_code;
1545 if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) {
1546 $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
1547 } else {
1548 $this->country = $obj->country;
1549 }
1550
1551 $this->phone = $obj->phone;
1552 $this->phone_perso = $obj->phone_perso;
1553 $this->phone_mobile = $obj->phone_mobile;
1554 $this->email = $obj->email;
1555 $this->url = $obj->url;
1556
1557 $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1558
1559 $this->photo = $obj->photo;
1560 $this->statut = $obj->statut;
1561 $this->status = $obj->statut;
1562 $this->public = $obj->public;
1563
1564 $this->datec = $this->db->jdate($obj->datec);
1565 $this->date_creation = $this->db->jdate($obj->datec);
1566 $this->datem = $this->db->jdate($obj->datem);
1567 $this->date_modification = $this->db->jdate($obj->datem);
1568 $this->datefin = $this->db->jdate($obj->datefin);
1569 $this->datevalid = $this->db->jdate($obj->datev);
1570 $this->date_validation = $this->db->jdate($obj->datev);
1571 $this->birth = $this->db->jdate($obj->birthday);
1572
1573 $this->default_lang = $obj->default_lang;
1574
1575 $this->note_private = $obj->note_private;
1576 $this->note_public = $obj->note_public;
1577 $this->morphy = $obj->morphy;
1578
1579 $this->typeid = $obj->fk_adherent_type;
1580 $this->type = $obj->type;
1581 $this->need_subscription = $obj->subscription;
1582
1583 $this->user_id = $obj->user_id;
1584 $this->user_login = $obj->user_login;
1585
1586 $this->model_pdf = $obj->model_pdf;
1587
1588 // Retrieve all extrafield
1589 // fetch optionals attributes and labels
1590 if ($fetch_optionals) {
1591 $this->fetch_optionals();
1592 }
1593
1594 // Load other properties
1595 if ($fetch_subscriptions) {
1596 $result = $this->fetch_subscriptions();
1597 }
1598
1599 return $this->id;
1600 } else {
1601 return 0;
1602 }
1603 } else {
1604 $this->error = $this->db->lasterror();
1605 return -1;
1606 }
1607 }
1608
1609
1610 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1619 public function fetch_subscriptions()
1620 {
1621 // phpcs:enable
1622 global $langs;
1623
1624 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1625
1626 $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
1627 $sql .= " c.tms as datem,";
1628 $sql .= " c.datec as datec,";
1629 $sql .= " c.dateadh as dateh,";
1630 $sql .= " c.datef as datef";
1631 $sql .= " FROM ".MAIN_DB_PREFIX."subscription as c";
1632 $sql .= " WHERE c.fk_adherent = ".((int) $this->id);
1633 $sql .= " ORDER BY c.dateadh";
1634 dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
1635
1636 $resql = $this->db->query($sql);
1637 if ($resql) {
1638 $this->subscriptions = array();
1639
1640 $i = 0;
1641 while ($obj = $this->db->fetch_object($resql)) {
1642 if ($i == 0) {
1643 $this->first_subscription_date = $this->db->jdate($obj->datec);
1644 $this->first_subscription_date_start = $this->db->jdate($obj->dateh);
1645 $this->first_subscription_date_end = $this->db->jdate($obj->datef);
1646 $this->first_subscription_amount = $obj->subscription;
1647 }
1648 $this->last_subscription_date = $this->db->jdate($obj->datec);
1649 $this->last_subscription_date_start = $this->db->jdate($obj->dateh);
1650 $this->last_subscription_date_end = $this->db->jdate($obj->datef);
1651 $this->last_subscription_amount = $obj->subscription;
1652
1653 $subscription = new Subscription($this->db);
1654 $subscription->id = $obj->rowid;
1655 $subscription->fk_adherent = $obj->fk_adherent;
1656 $subscription->fk_type = $obj->fk_type;
1657 $subscription->amount = $obj->subscription;
1658 $subscription->note = $obj->note_public;
1659 $subscription->note_public = $obj->note_public;
1660 $subscription->fk_bank = $obj->fk_bank;
1661 $subscription->datem = $this->db->jdate($obj->datem);
1662 $subscription->datec = $this->db->jdate($obj->datec);
1663 $subscription->dateh = $this->db->jdate($obj->dateh);
1664 $subscription->datef = $this->db->jdate($obj->datef);
1665
1666 $this->subscriptions[] = $subscription;
1667
1668 $i++;
1669 }
1670 return 1;
1671 } else {
1672 $this->error = $this->db->error().' sql='.$sql;
1673 return -1;
1674 }
1675 }
1676
1677
1684 public function fetchPartnerships($mode)
1685 {
1686 global $langs;
1687
1688 require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php';
1689
1690
1691 $this->partnerships[] = array();
1692
1693 return 1;
1694 }
1695
1696
1712 public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
1713 {
1714 global $user;
1715
1716 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1717
1718 $error = 0;
1719
1720 // Clean parameters
1721 if (!$amount) {
1722 $amount = 0;
1723 }
1724
1725 $this->db->begin();
1726
1727 if ($datesubend) {
1728 $datefin = $datesubend;
1729 } else {
1730 // If no end date, end date = date + 1 year - 1 day
1731 $datefin = dol_time_plus_duree($date, 1, 'y');
1732 $datefin = dol_time_plus_duree($datefin, -1, 'd');
1733 }
1734
1735 // Create subscription
1736 $subscription = new Subscription($this->db);
1737 $subscription->fk_adherent = $this->id;
1738 $subscription->dateh = $date; // Date of new subscription
1739 $subscription->datef = $datefin; // End data of new subscription
1740 $subscription->amount = $amount;
1741 $subscription->note = $label; // deprecated
1742 $subscription->note_public = $label;
1743 $subscription->fk_type = $fk_type;
1744
1745 if (empty($subscription->user_creation_id)) {
1746 $subscription->user_creation_id = $user->id;
1747 }
1748
1749 $rowid = $subscription->create($user);
1750 if ($rowid > 0) {
1751 // Update denormalized subscription end date (read database subscription to find values)
1752 // This will also update this->datefin
1753 $result = $this->update_end_date($user);
1754 if ($result > 0) {
1755 // Change properties of object (used by triggers)
1756 $this->last_subscription_date = dol_now();
1757 $this->last_subscription_date_start = $date;
1758 $this->last_subscription_date_end = $datefin;
1759 $this->last_subscription_amount = $amount;
1760 }
1761
1762 if (!$error) {
1763 $this->db->commit();
1764 return $rowid;
1765 } else {
1766 $this->db->rollback();
1767 return -2;
1768 }
1769 } else {
1770 $this->setErrorsFromObject($subscription);
1771 $this->db->rollback();
1772 return -1;
1773 }
1774 }
1775
1776
1796 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 = '')
1797 {
1798 global $conf, $langs, $user, $mysoc;
1799
1800 $error = 0;
1801
1802 $this->invoice = null; // This will contains invoice if an invoice is created
1803
1804 dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".
1805 $paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
1806
1807 // Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
1808 if ($option == 'bankdirect' && $accountid) {
1809 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1810
1811 $acct = new Account($this->db);
1812 $result = $acct->fetch($accountid);
1813
1814 $dateop = $paymentdate;
1815
1816 $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, 0, $user, $emetteur_nom, $emetteur_banque);
1817 if ($insertid > 0) {
1818 $inserturlid = $acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
1819 if ($inserturlid > 0) {
1820 // Update table subscription
1821 $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".((int) $insertid);
1822 $sql .= " WHERE rowid=".((int) $subscriptionid);
1823
1824 dol_syslog("subscription::subscription", LOG_DEBUG);
1825 $resql = $this->db->query($sql);
1826 if (!$resql) {
1827 $error++;
1828 $this->error = $this->db->lasterror();
1829 $this->errors[] = $this->error;
1830 }
1831 } else {
1832 $error++;
1833 $this->setErrorsFromObject($acct);
1834 }
1835 } else {
1836 $error++;
1837 $this->setErrorsFromObject($acct);
1838 }
1839 }
1840
1841 // If option chosen, we create invoice
1842 if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
1843 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1844 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
1845
1846 $invoice = new Facture($this->db);
1847 $customer = new Societe($this->db);
1848
1849 if (!$error) {
1850 if (!($this->fk_soc > 0)) { // If not yet linked to a company
1851 if ($autocreatethirdparty) {
1852 // Create a linked thirdparty to member
1853 $companyalias = '';
1854 $fullname = $this->getFullName($langs);
1855
1856 if ($this->morphy == 'mor') {
1857 $companyname = $this->company;
1858 if (!empty($fullname)) {
1859 $companyalias = $fullname;
1860 }
1861 } else {
1862 $companyname = $fullname;
1863 if (!empty($this->company)) {
1864 $companyalias = $this->company;
1865 }
1866 }
1867
1868 $result = $customer->create_from_member($this, (string) $companyname, $companyalias);
1869 if ($result < 0) {
1870 $this->error = $customer->error;
1871 $this->errors = $customer->errors;
1872 $error++;
1873 } else {
1874 $this->fk_soc = $result;
1875 }
1876 } else {
1877 $langs->load("errors");
1878 $this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1879 $this->errors[] = $this->error;
1880 $error++;
1881 }
1882 }
1883 }
1884 if (!$error) {
1885 $result = $customer->fetch($this->fk_soc);
1886 if ($result <= 0) {
1887 $this->error = $customer->error;
1888 $this->errors = $customer->errors;
1889 $error++;
1890 }
1891 }
1892
1893 if (!$error) {
1894 // Create draft invoice
1895 $invoice->type = Facture::TYPE_STANDARD;
1896 $invoice->cond_reglement_id = $customer->cond_reglement_id;
1897 if (empty($invoice->cond_reglement_id)) {
1898 $paymenttermstatic = new PaymentTerm($this->db);
1899 $invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
1900 if (empty($invoice->cond_reglement_id)) {
1901 $error++;
1902 $this->error = 'ErrorNoPaymentTermRECEPFound';
1903 $this->errors[] = $this->error;
1904 }
1905 }
1906 $invoice->socid = $this->fk_soc;
1907 // set customer's payment bank account on the invoice
1908 if (!empty($customer->fk_account)) {
1909 $invoice->fk_account = $customer->fk_account;
1910 } elseif (getDolGlobalString('FACTURE_RIB_NUMBER')) {
1911 // set default bank account from invoice module settings
1912 $invoice->fk_account = (int) getDolGlobalString('FACTURE_RIB_NUMBER');
1913 }
1914 //set customer's payment method on the invoice
1915 if (!empty($customer->mode_reglement_id)) {
1916 $invoice->mode_reglement_id = $customer->mode_reglement_id;
1917 }
1918 //$invoice->date = $datesubscription;
1919 $invoice->date = dol_now();
1920
1921 // Possibility to add external linked objects with hooks
1922 $invoice->linked_objects['subscription'] = $subscriptionid;
1923 if (GETPOSTISARRAY('other_linked_objects')) {
1924 $invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int'));
1925 }
1926
1927 $result = $invoice->create($user);
1928 if ($result <= 0) {
1929 $this->error = $invoice->error;
1930 $this->errors = $invoice->errors;
1931 $error++;
1932 } else {
1933 $this->invoice = $invoice;
1934 }
1935 }
1936
1937 if (!$error) {
1938 // Add line to draft invoice
1939 $idprodsubscription = 0;
1940 if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
1941 $idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
1942 }
1943
1944 $vattouse = 0;
1945 if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
1946 $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
1947 }
1948 //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1949 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1950 $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, 0, 'TTC', $amount, 1);
1951 if ($result <= 0) {
1952 $this->error = $invoice->error;
1953 $this->errors = $invoice->errors;
1954 $error++;
1955 }
1956 }
1957
1958 if (!$error) {
1959 // Validate invoice
1960 $result = $invoice->validate($user);
1961 if ($result <= 0) {
1962 $this->error = $invoice->error;
1963 $this->errors = $invoice->errors;
1964 $error++;
1965 }
1966 }
1967
1968 if (!$error) {
1969 // TODO Link invoice with subscription ?
1970 }
1971
1972 // Add payment onto invoice
1973 if (!$error && $option == 'bankviainvoice' && $accountid) {
1974 require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1975 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1976 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
1977
1978 $amounts = array();
1979 $amounts[$invoice->id] = (float) price2num($amount);
1980
1981 $paiement = new Paiement($this->db);
1982 $paiement->datepaye = $paymentdate;
1983 $paiement->amounts = $amounts;
1984 $paiement->paiementcode = $operation;
1985 $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
1986 $paiement->num_payment = $num_chq;
1987 $paiement->note_public = $label;
1988 $paiement->ext_payment_id = $ext_payment_id;
1989 $paiement->ext_payment_site = $ext_payment_site;
1990
1991 if (!$error) {
1992 // Create payment line for invoice
1993 $paiement_id = $paiement->create($user);
1994 if (!($paiement_id > 0)) {
1995 $this->error = $paiement->error;
1996 $this->errors = $paiement->errors;
1997 $error++;
1998 }
1999 }
2000
2001 if (!$error) {
2002 // Add transaction into bank account
2003 $bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
2004 if (!($bank_line_id > 0)) {
2005 $this->error = $paiement->error;
2006 $this->errors = $paiement->errors;
2007 $error++;
2008 }
2009 }
2010
2011 if (!$error && !empty($bank_line_id)) {
2012 // Update fk_bank into subscription table
2013 $sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.((int) $bank_line_id);
2014 $sql .= ' WHERE rowid='.((int) $subscriptionid);
2015
2016 $result = $this->db->query($sql);
2017 if (!$result) {
2018 $error++;
2019 }
2020 }
2021
2022 if (!$error) {
2023 // Set invoice as paid
2024 $invoice->setPaid($user);
2025 }
2026 }
2027
2028 if (!$error) {
2029 // Define output language
2030 $outputlangs = $langs;
2031 $newlang = '';
2032 $lang_id = GETPOST('lang_id');
2033 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
2034 $newlang = $lang_id;
2035 }
2036 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
2037 $newlang = $customer->default_lang;
2038 }
2039 if (!empty($newlang)) {
2040 $outputlangs = new Translate("", $conf);
2041 $outputlangs->setDefaultLang($newlang);
2042 }
2043 // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
2044 //if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
2045
2046 $invoice->fetch($invoice->id); // Reload invoice object data
2047 $invoice->generateDocument($invoice->model_pdf, $outputlangs);
2048 }
2049 }
2050
2051 if ($error) {
2052 return -1;
2053 } else {
2054 return 1;
2055 }
2056 }
2057
2058
2065 public function validate($user)
2066 {
2067 global $langs, $conf;
2068
2069 $error = 0;
2070 $now = dol_now();
2071
2072 // Check parameters
2073 if ($this->statut == self::STATUS_VALIDATED) {
2074 dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
2075 return 0;
2076 }
2077
2078 $this->db->begin();
2079
2080 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2081 $sql .= " statut = ".self::STATUS_VALIDATED;
2082 $sql .= ", datevalid = '".$this->db->idate($now)."'";
2083 $sql .= ", fk_user_valid = ".((int) $user->id);
2084 $sql .= " WHERE rowid = ".((int) $this->id);
2085
2086 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
2087 $result = $this->db->query($sql);
2088 if ($result) {
2089 $this->statut = self::STATUS_VALIDATED;
2090
2091 // Call trigger
2092 $result = $this->call_trigger('MEMBER_VALIDATE', $user);
2093 if ($result < 0) {
2094 $error++;
2095 $this->db->rollback();
2096 return -1;
2097 }
2098 // End call triggers
2099
2100 $this->datevalid = $now;
2101
2102 $this->db->commit();
2103 return 1;
2104 } else {
2105 $this->error = $this->db->error();
2106 $this->db->rollback();
2107 return -1;
2108 }
2109 }
2110
2111
2118 public function resiliate($user)
2119 {
2120 global $langs, $conf;
2121
2122 $error = 0;
2123
2124 // Check parameters
2125 if ($this->statut == self::STATUS_RESILIATED) {
2126 dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2127 return 0;
2128 }
2129
2130 $this->db->begin();
2131
2132 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2133 $sql .= " statut = ".((int) self::STATUS_RESILIATED);
2134 $sql .= ", fk_user_valid = ".((int) $user->id);
2135 $sql .= " WHERE rowid = ".((int) $this->id);
2136
2137 $result = $this->db->query($sql);
2138 if ($result) {
2139 $this->statut = self::STATUS_RESILIATED;
2140
2141 // Call trigger
2142 $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2143 if ($result < 0) {
2144 $error++;
2145 $this->db->rollback();
2146 return -1;
2147 }
2148 // End call triggers
2149
2150 $this->db->commit();
2151 return 1;
2152 } else {
2153 $this->error = $this->db->error();
2154 $this->db->rollback();
2155 return -1;
2156 }
2157 }
2158
2168 public function exclude($user)
2169 {
2170 $error = 0;
2171
2172 // Check parameters
2173 if ($this->statut == self::STATUS_EXCLUDED) {
2174 dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2175 return 0;
2176 }
2177
2178 $this->db->begin();
2179
2180 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2181 $sql .= " statut = ".((int) self::STATUS_EXCLUDED);
2182 $sql .= ", fk_user_valid = ".((int) $user->id);
2183 $sql .= " WHERE rowid = ".((int) $this->id);
2184
2185 $result = $this->db->query($sql);
2186 if ($result) {
2187 $this->statut = self::STATUS_EXCLUDED;
2188
2189 // Call trigger
2190 $result = $this->call_trigger('MEMBER_EXCLUDE', $user);
2191 if ($result < 0) {
2192 $error++;
2193 $this->db->rollback();
2194 return -1;
2195 }
2196 // End call triggers
2197
2198 $this->db->commit();
2199 return 1;
2200 } else {
2201 $this->error = $this->db->error();
2202 $this->db->rollback();
2203 return -1;
2204 }
2205 }
2206
2207 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2213 public function add_to_abo()
2214 {
2215 // phpcs:enable
2216 global $langs;
2217
2218 include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2219 $mailmanspip = new MailmanSpip($this->db);
2220
2221 $err = 0;
2222
2223 // mailman
2224 if (getDolGlobalString('ADHERENT_USE_MAILMAN') && isModEnabled('mailmanspip')) {
2225 $result = $mailmanspip->add_to_mailman($this);
2226
2227 if ($result < 0) {
2228 if (!empty($mailmanspip->error)) {
2229 $this->errors[] = $mailmanspip->error;
2230 }
2231 $err += 1;
2232 }
2233 foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) {
2234 $langs->load("errors");
2235 $this->errors[] = $langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
2236 }
2237 foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) {
2238 $langs->load("mailmanspip");
2239 $this->mesgs[] = $langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
2240 }
2241 }
2242
2243 // spip
2244 if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2245 $result = $mailmanspip->add_to_spip($this);
2246 if ($result < 0) {
2247 $this->errors[] = $mailmanspip->error;
2248 $err += 1;
2249 }
2250 }
2251 if ($err) {
2252 return -$err;
2253 } else {
2254 return 1;
2255 }
2256 }
2257
2258
2259 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2265 public function del_to_abo()
2266 {
2267 // phpcs:enable
2268 global $conf, $langs;
2269
2270 include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2271 $mailmanspip = new MailmanSpip($this->db);
2272
2273 $err = 0;
2274
2275 // mailman
2276 if (getDolGlobalString('ADHERENT_USE_MAILMAN')) {
2277 $result = $mailmanspip->del_to_mailman($this);
2278 if ($result < 0) {
2279 if (!empty($mailmanspip->error)) {
2280 $this->errors[] = $mailmanspip->error;
2281 }
2282 $err += 1;
2283 }
2284
2285 foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) {
2286 $langs->load("errors");
2287 $this->errors[] = $langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
2288 }
2289 foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) {
2290 $langs->load("mailmanspip");
2291 $this->mesgs[] = $langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
2292 }
2293 }
2294
2295 if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2296 $result = $mailmanspip->del_to_spip($this);
2297 if ($result < 0) {
2298 $this->errors[] = $mailmanspip->error;
2299 $err += 1;
2300 }
2301 }
2302 if ($err) {
2303 // error
2304 return -$err;
2305 } else {
2306 return 1;
2307 }
2308 }
2309
2310
2316 public function getCivilityLabel()
2317 {
2318 global $langs;
2319 $langs->load("dict");
2320
2321 $code = (empty($this->civility_id) ? '' : $this->civility_id);
2322 if (empty($code)) {
2323 return '';
2324 }
2325 return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
2326 }
2327
2334 public function getTooltipContentArray($params)
2335 {
2336 global $langs;
2337
2338 $langs->loadLangs(['members', 'companies']);
2339 $nofetch = !empty($params['nofetch']);
2340
2341 $datas = array();
2342
2343 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2344 $langs->load("users");
2345 return ['optimize' => $langs->trans("ShowUser")];
2346 }
2347 if (!empty($this->photo)) {
2348 $photo = '<div class="photointooltip floatright">';
2349 $photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1);
2350 $photo .= '</div>';
2351 $datas['photo'] = $photo;
2352 }
2353
2354 $datas['divopen'] = '<div class="centpercent">';
2355 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Member").'</u> '.$this->getLibStatut(4);
2356 if (!empty($this->morphy)) {
2357 $datas['picto'] .= '&nbsp;' . $this->getmorphylib('', 1);
2358 }
2359 if (!empty($this->ref)) {
2360 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
2361 }
2362 if (!empty($this->login)) {
2363 $datas['login'] = '<br><b>'.$langs->trans('Login').':</b> '.$this->login;
2364 }
2365 if (!empty($this->firstname) || !empty($this->lastname)) {
2366 $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
2367 }
2368 if (!empty($this->company)) {
2369 $datas['company'] = '<br><b>'.$langs->trans('Company').':</b> '.$this->company;
2370 }
2371 if (!empty($this->email)) {
2372 $datas['email'] = '<br><b>'.$langs->trans("EMail").':</b> '.$this->email;
2373 }
2374 $datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs);
2375 // show categories for this record only in ajax to not overload lists
2376 if (isModEnabled('category') && !$nofetch) {
2377 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
2378 $form = new Form($this->db);
2379 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_MEMBER, 1);
2380 }
2381 $datas['divclose'] = '</div>';
2382
2383 return $datas;
2384 }
2385
2399 public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0)
2400 {
2401 global $conf, $langs, $hookmanager;
2402
2403 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpictoimg) {
2404 $withpictoimg = 0;
2405 }
2406
2407 $result = '';
2408 $linkstart = '';
2409 $linkend = '';
2410 $classfortooltip = 'classfortooltip';
2411 $dataparams = '';
2412 $params = [
2413 'id' => $this->id,
2414 'objecttype' => $this->element,
2415 'option' => $option,
2416 'nofetch' => 1,
2417 ];
2418 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
2419 $classfortooltip = 'classforajaxtooltip';
2420 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
2421 $label = '';
2422 } else {
2423 $label = implode($this->getTooltipContentArray($params));
2424 }
2425
2426 $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.((int) $this->id);
2427 if ($option == 'subscription') {
2428 $url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.((int) $this->id);
2429 }
2430
2431 if ($option != 'nolink') {
2432 // Add param to save lastsearch_values or not
2433 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2434 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
2435 $add_save_lastsearch_values = 1;
2436 }
2437 if ($add_save_lastsearch_values) {
2438 $url .= '&save_lastsearch_values=1';
2439 }
2440 }
2441
2442 $linkstart .= '<a href="'.$url.'"';
2443 $linkclose = "";
2444 if (empty($notooltip)) {
2445 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2446 $langs->load("users");
2447 $label = $langs->trans("ShowUser");
2448 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
2449 }
2450 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
2451 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
2452 }
2453
2454 $linkstart .= $linkclose.'>';
2455 $linkend = '</a>';
2456
2457 $result .= $linkstart;
2458
2459 if ($withpictoimg) {
2460 $paddafterimage = '';
2461 if (abs($withpictoimg) == 1 || abs($withpictoimg) == 4) {
2462 $morecss .= ' paddingrightonly';
2463 }
2464 // Only picto
2465 if ($withpictoimg > 0) {
2466 $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1).'</span>';
2467 } else {
2468 // Picto must be a photo
2469 $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'"'.($paddafterimage ? ' '.$paddafterimage : '').'>';
2470 $picto .= Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.(($withpictoimg == -3 || $withpictoimg == -4) ? 'small' : ''), 'mini', 0, 1);
2471 $picto .= '</span>';
2472 }
2473 $result .= $picto;
2474 }
2475 if (($withpictoimg > -2 && $withpictoimg != 2) || $withpictoimg == -4) {
2476 if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2477 $result .= '<span class="nopadding valignmiddle'.((!isset($this->statut) || $this->statut) ? '' : ' strikefordisabled').
2478 ($morecss ? ' usertext'.$morecss : '').'">';
2479 }
2480 if ($mode == 'login') {
2481 $result .= dol_trunc(isset($this->login) ? $this->login : '', $maxlen);
2482 } elseif ($mode == 'ref') {
2483 $result .= $this->ref;
2484 } else {
2485 $result .= $this->getFullName($langs, 0, ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2486 }
2487 if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2488 $result .= '</span>';
2489 }
2490 }
2491
2492 $result .= $linkend;
2493
2494 if ($addlinktonotes) {
2495 if ($this->note_private) {
2496 $notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($this->note_private, 1);
2497 $result .= ' <span class="note inline-block">';
2498 $result .= '<a href="'.DOL_URL_ROOT.'/adherents/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
2499 $result .= img_picto('', 'note');
2500 $result .= '</a>';
2501 $result .= '</span>';
2502 }
2503 }
2504 global $action;
2505 $hookmanager->initHooks(array($this->element . 'dao'));
2506 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
2507 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2508 if ($reshook > 0) {
2509 $result = $hookmanager->resPrint;
2510 } else {
2511 $result .= $hookmanager->resPrint;
2512 }
2513 return $result;
2514 }
2515
2522 public function getLibStatut($mode = 0)
2523 {
2524 return $this->LibStatut($this->status, $this->need_subscription, $this->datefin, $mode);
2525 }
2526
2527 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2537 public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
2538 {
2539 // phpcs:enable
2540 global $langs;
2541 $langs->load("members");
2542
2543 $statusType = '';
2544 $labelStatus = '';
2545 $labelStatusShort = '';
2546
2547 if ($status == self::STATUS_DRAFT) {
2548 $statusType = 'status0';
2549 $labelStatus = $langs->trans("MemberStatusDraft");
2550 $labelStatusShort = $langs->trans("MemberStatusDraftShort");
2551 } elseif ($status >= self::STATUS_VALIDATED) {
2552 if ($need_subscription === 0) {
2553 $statusType = 'status4';
2554 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusNoSubscription");
2555 $labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
2556 } elseif (!$date_end_subscription) {
2557 $statusType = 'status1';
2558 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("WaitingSubscription");
2559 $labelStatusShort = $langs->trans("WaitingSubscriptionShort");
2560 } elseif ($date_end_subscription < dol_now()) { // expired
2561 $statusType = 'status2';
2562 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusActiveLate");
2563 $labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
2564 } else {
2565 $statusType = 'status4';
2566 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusPaid");
2567 $labelStatusShort = $langs->trans("MemberStatusPaidShort");
2568 }
2569 } elseif ($status == self::STATUS_RESILIATED) {
2570 $statusType = 'status6';
2571 $labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
2572 $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
2573 } elseif ($status == self::STATUS_EXCLUDED) {
2574 $statusType = 'status10';
2575 $labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
2576 $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
2577 }
2578
2579 return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
2580 }
2581
2582
2588 public function loadStateBoard()
2589 {
2590 global $conf;
2591
2592 $this->nb = array();
2593
2594 $sql = "SELECT count(a.rowid) as nb";
2595 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2596 $sql .= " WHERE a.statut > 0";
2597 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2598
2599 $resql = $this->db->query($sql);
2600 if ($resql) {
2601 while ($obj = $this->db->fetch_object($resql)) {
2602 $this->nb["members"] = $obj->nb;
2603 }
2604 $this->db->free($resql);
2605 return 1;
2606 } else {
2607 dol_print_error($this->db);
2608 $this->error = $this->db->error();
2609 return -1;
2610 }
2611 }
2612
2613 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2621 public function load_board($user, $mode)
2622 {
2623 // phpcs:enable
2624 global $conf, $langs;
2625
2626 if ($user->socid) {
2627 return -1; // protection pour eviter appel par utilisateur externe
2628 }
2629
2630 $now = dol_now();
2631
2632 $sql = "SELECT a.rowid, a.datefin, a.statut";
2633 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2634 $sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
2635 $sql .= " WHERE a.fk_adherent_type = t.rowid";
2636 if ($mode == 'expired') {
2637 $sql .= " AND a.statut = ".self::STATUS_VALIDATED;
2638 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2639 $sql .= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = '1')";
2640 } elseif ($mode == 'shift') {
2641 $sql .= " AND a.statut = ".self::STATUS_DRAFT;
2642 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2643 }
2644
2645 $resql = $this->db->query($sql);
2646 if ($resql) {
2647 $langs->load("members");
2648
2649 $warning_delay = 0;
2650 $url = '';
2651 $label = '';
2652 $labelShort = '';
2653
2654 if ($mode == 'expired') {
2655 $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2656 $label = $langs->trans("MembersWithSubscriptionToReceive");
2657 $labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
2658 $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_VALIDATED.'&amp;filter=outofdate';
2659 } elseif ($mode == 'shift') {
2660 $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2661 $url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut='.self::STATUS_DRAFT;
2662 $label = $langs->trans("MembersListToValid");
2663 $labelShort = $langs->trans("ToValidate");
2664 }
2665
2666 $response = new WorkboardResponse();
2667 $response->warning_delay = $warning_delay;
2668 $response->label = $label;
2669 $response->labelShort = $labelShort;
2670 $response->url = $url;
2671 $response->img = img_object('', "user");
2672
2673 $adherentstatic = new Adherent($this->db);
2674
2675 while ($obj = $this->db->fetch_object($resql)) {
2676 $response->nbtodo++;
2677
2678 $adherentstatic->datefin = $this->db->jdate($obj->datefin);
2679 $adherentstatic->statut = $obj->statut;
2680 $adherentstatic->status = $obj->statut;
2681
2682 if ($adherentstatic->hasDelay()) {
2683 $response->nbtodolate++;
2684 }
2685 }
2686
2687 return $response;
2688 } else {
2689 dol_print_error($this->db);
2690 $this->error = $this->db->error();
2691 return -1;
2692 }
2693 }
2694
2695
2707 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2708 {
2709 global $conf, $langs;
2710
2711 $langs->load("orders");
2712
2713 if (!dol_strlen($modele)) {
2714 $modele = 'standard';
2715
2716 if ($this->model_pdf) {
2717 $modele = $this->model_pdf;
2718 } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2719 $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2720 }
2721 }
2722
2723 $modelpath = "core/modules/member/doc/";
2724
2725 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2726 }
2727
2728
2736 public function initAsSpecimen()
2737 {
2738 global $user, $langs;
2739 $now = dol_now();
2740
2741 // Initialise parameters
2742 $this->id = 0;
2743 $this->ref = 'ABC001';
2744 $this->entity = 1;
2745 $this->specimen = 1;
2746 $this->civility_id = 'MR';
2747 $this->lastname = 'DOLIBARR';
2748 $this->firstname = 'SPECIMEN';
2749 $this->gender = 'man';
2750 $this->login = 'dolibspec';
2751 $this->pass = 'dolibspec';
2752 $this->company = 'Societe ABC';
2753 $this->address = '61 jump street';
2754 $this->zip = '75000';
2755 $this->town = 'Paris';
2756 $this->country_id = 1;
2757 $this->country_code = 'FR';
2758 $this->country = 'France';
2759 $this->morphy = 'mor';
2760 $this->email = 'specimen@specimen.com';
2761 $this->socialnetworks = array(
2762 'skype' => 'skypepseudo',
2763 'twitter' => 'twitterpseudo',
2764 'facebook' => 'facebookpseudo',
2765 'linkedin' => 'linkedinpseudo',
2766 );
2767 $this->phone = '0999999999';
2768 $this->phone_perso = '0999999998';
2769 $this->phone_mobile = '0999999997';
2770 $this->note_public = 'This is a public note';
2771 $this->note_private = 'This is a private note';
2772 $this->birth = $now;
2773 $this->photo = '';
2774 $this->public = 1;
2775 $this->statut = self::STATUS_DRAFT;
2776 $this->status = self::STATUS_DRAFT;
2777
2778 $this->datefin = $now;
2779 $this->datevalid = $now;
2780 $this->default_lang = '';
2781
2782 $this->typeid = 1; // Id type adherent
2783 $this->type = 'Type adherent'; // Libelle type adherent
2784 $this->need_subscription = 0;
2785
2786 $this->first_subscription_date = $now;
2787 $this->first_subscription_date_start = $this->first_subscription_date;
2788 $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2789 $this->first_subscription_amount = 10;
2790
2791 $this->last_subscription_date = $this->first_subscription_date;
2792 $this->last_subscription_date_start = $this->first_subscription_date;
2793 $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2794 $this->last_subscription_amount = 10;
2795 return 1;
2796 }
2797
2798
2799 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2800 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2810 public function _load_ldap_dn($info, $mode = 0)
2811 {
2812 // phpcs:enable
2813 global $conf;
2814 $dn = '';
2815 if ($mode == 0) {
2816 $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')]."," . getDolGlobalString('LDAP_MEMBER_DN');
2817 }
2818 if ($mode == 1) {
2819 $dn = getDolGlobalString('LDAP_MEMBER_DN');
2820 }
2821 if ($mode == 2) {
2822 $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')];
2823 }
2824 return $dn;
2825 }
2826
2827
2828 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2829 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2835 public function _load_ldap_info()
2836 {
2837 // phpcs:enable
2838 global $conf, $langs;
2839
2840 $info = array();
2841 $socialnetworks = getArrayOfSocialNetworks();
2842 $keymodified = false;
2843
2844 // Object classes
2845 $info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
2846
2847 $this->fullname = $this->getFullName($langs);
2848
2849 // For avoid ldap error when firstname and lastname are empty
2850 if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
2851 $this->fullname = $this->company;
2852 $this->lastname = $this->company;
2853 }
2854
2855 // Possible LDAP KEY (constname => varname)
2856 $ldapkey = array(
2857 'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
2858 'LDAP_MEMBER_FIELD_NAME' => 'lastname',
2859 'LDAP_MEMBER_FIELD_LOGIN' => 'login',
2860 'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
2861 'LDAP_MEMBER_FIELD_MAIL' => 'email'
2862 );
2863
2864 // Member
2865 foreach ($ldapkey as $constname => $varname) {
2866 if (!empty($this->$varname) && getDolGlobalString($constname)) {
2867 $info[getDolGlobalString($constname)] = $this->$varname;
2868
2869 // Check if it is the LDAP key and if its value has been changed
2870 if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
2871 if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
2872 $keymodified = true; // For check if LDAP key has been modified
2873 }
2874 }
2875 }
2876 }
2877 if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
2878 $info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
2879 }
2880 if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
2881 $info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
2882 }
2883 if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
2884 $info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
2885 }
2886 if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
2887 $info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
2888 }
2889 if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
2890 $info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
2891 }
2892 if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
2893 $info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
2894 }
2895 if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
2896 $info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
2897 }
2898 foreach ($socialnetworks as $key => $value) {
2899 if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))) {
2900 $info[getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
2901 }
2902 }
2903 if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
2904 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
2905 }
2906 if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
2907 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
2908 }
2909 if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
2910 $info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
2911 }
2912 if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
2913 $info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
2914 }
2915 if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
2916 $info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
2917 }
2918 if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
2919 $info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
2920 }
2921 if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
2922 $info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
2923 }
2924 if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
2925 $info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
2926 }
2927 if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
2928 $info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
2929 }
2930
2931 // When password is modified
2932 if (!empty($this->pass)) {
2933 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2934 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
2935 }
2936 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2937 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2938 }
2939 } elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
2940 // Set LDAP password if possible
2941 // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2942 if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
2943 // Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
2944 if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
2945 if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2946 // Create OpenLDAP MD5 password from Dolibarr MD5 password
2947 // Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
2948 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
2949 }
2950 }
2951 } elseif (!empty($this->pass_indatabase)) {
2952 // Use $this->pass_indatabase value if exists
2953 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2954 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
2955 }
2956 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2957 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2958 }
2959 }
2960 }
2961
2962 // Subscriptions
2963 if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
2964 $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
2965 }
2966 if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
2967 $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
2968 }
2969 if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
2970 $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
2971 }
2972 if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
2973 $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
2974 }
2975
2976 return $info;
2977 }
2978
2979
2986 public function info($id)
2987 {
2988 $sql = 'SELECT a.rowid, a.datec as datec,';
2989 $sql .= ' a.datevalid as datev,';
2990 $sql .= ' a.tms as datem,';
2991 $sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2992 $sql .= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
2993 $sql .= ' WHERE a.rowid = '.((int) $id);
2994
2995 dol_syslog(get_class($this)."::info", LOG_DEBUG);
2996 $result = $this->db->query($sql);
2997 if ($result) {
2998 if ($this->db->num_rows($result)) {
2999 $obj = $this->db->fetch_object($result);
3000
3001 $this->id = $obj->rowid;
3002
3003 $this->user_creation_id = $obj->fk_user_author;
3004 $this->user_validation_id = $obj->fk_user_valid;
3005 $this->user_modification_id = $obj->fk_user_mod;
3006 $this->date_creation = $this->db->jdate($obj->datec);
3007 $this->date_validation = $this->db->jdate($obj->datev);
3008 $this->date_modification = $this->db->jdate($obj->datem);
3009 }
3010
3011 $this->db->free($result);
3012 } else {
3013 dol_print_error($this->db);
3014 }
3015 }
3016
3022 public function getNbOfEMailings()
3023 {
3024 $sql = "SELECT count(mc.email) as nb";
3025 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
3026 $sql .= " WHERE mc.email = '".$this->db->escape($this->email)."'";
3027 $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec success
3028
3029 $resql = $this->db->query($sql);
3030 if ($resql) {
3031 $obj = $this->db->fetch_object($resql);
3032 $nb = $obj->nb;
3033
3034 $this->db->free($resql);
3035 return $nb;
3036 } else {
3037 $this->error = $this->db->error();
3038 return -1;
3039 }
3040 }
3041
3052 public function setCategories($categories)
3053 {
3054 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
3055 return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
3056 }
3057
3066 public static function replaceThirdparty($db, $origin_id, $dest_id)
3067 {
3068 $tables = array('adherent');
3069
3070 return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
3071 }
3072
3078 public function hasDelay()
3079 {
3080 global $conf;
3081
3082 //Only valid members
3083 if ($this->statut != self::STATUS_VALIDATED) {
3084 return false;
3085 }
3086 if (!$this->datefin) {
3087 return false;
3088 }
3089
3090 $now = dol_now();
3091
3092 return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
3093 }
3094
3095
3104 public function sendReminderForExpiredSubscription($daysbeforeendlist = '10', $fk_adherent_type = 0)
3105 {
3106 global $conf, $langs, $mysoc, $user;
3107
3108 $error = 0;
3109 $this->output = '';
3110 $this->error = '';
3111
3112 $blockingerrormsg = '';
3113
3114 if (!isModEnabled('member')) { // Should not happen. If module disabled, cron job should not be visible.
3115 $langs->load("agenda");
3116 $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3117 return 0;
3118 }
3119 if (!getDolGlobalString('MEMBER_REMINDER_EMAIL')) {
3120 $langs->load("agenda");
3121 $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3122 return 0;
3123 }
3124
3125 $now = dol_now();
3126 $nbok = 0;
3127 $nbko = 0;
3128
3129 $listofmembersok = array();
3130 $listofmembersko = array();
3131
3132 $arraydaysbeforeend = explode(';', $daysbeforeendlist);
3133 foreach ($arraydaysbeforeend as $daysbeforeend) { // Loop on each delay
3134 dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
3135
3136 if (!is_numeric($daysbeforeend)) {
3137 $blockingerrormsg = "Value for delta is not a numeric value";
3138 $nbko++;
3139 break;
3140 }
3141
3142 $tmp = dol_getdate($now);
3143 $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
3144 $datetosearchforend = dol_time_plus_duree(dol_mktime(23, 59, 59, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
3145
3146 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
3147 $sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
3148 $sql .= " AND statut = 1";
3149 $sql .= " AND datefin >= '".$this->db->idate($datetosearchfor)."'";
3150 $sql .= " AND datefin <= '".$this->db->idate($datetosearchforend)."'";
3151 if ((int) $fk_adherent_type > 0) {
3152 $sql .= " AND fk_adherent_type = ".((int) $fk_adherent_type);
3153 }
3154 //$sql .= " LIMIT 10000";
3155
3156 $resql = $this->db->query($sql);
3157 if ($resql) {
3158 $num_rows = $this->db->num_rows($resql);
3159
3160 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
3161 $formmail = new FormMail($this->db);
3162
3163 $i = 0;
3164 while ($i < $num_rows) {
3165 $obj = $this->db->fetch_object($resql);
3166
3167 // A new object for each member: fetch() does not reset the properties loaded for the previous member,
3168 // like ->thirdparty that would be reused for a member that has no third party.
3169 $adherent = new Adherent($this->db);
3170 $adherent->fetch($obj->rowid, '', 0, '', true, true);
3171
3172 if (empty($adherent->email)) {
3173 $nbko++;
3174 $listofmembersko[$adherent->id] = $adherent->id;
3175 } else {
3176 $thirdpartyres = $adherent->fetch_thirdparty();
3177 if ($thirdpartyres === -1) {
3178 $languagecodeformember = $mysoc->default_lang;
3179 } else {
3180 // 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.
3181 $languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : (is_object($adherent->thirdparty) ? $adherent->thirdparty->country_code : ''));
3182 $languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
3183 }
3184 if (!empty($adherent->default_lang)) {
3185 // The language set on the member itself has priority
3186 $languagecodeformember = $adherent->default_lang;
3187 }
3188
3189 // Send reminder email
3190 $outputlangs = new Translate('', $conf);
3191 $outputlangs->setDefaultLang($languagecodeformember);
3192 $outputlangs->loadLangs(array("main", "members"));
3193 dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
3194
3195 $arraydefaultmessage = null;
3196 $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
3197
3198 if (!empty($labeltouse)) {
3199 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
3200 }
3201
3202 if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
3203 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
3204 //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
3205 complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
3206
3207 $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
3208 $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
3209 $from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
3210 $to = $adherent->email;
3211 $cc = getDolGlobalString('ADHERENT_CC_MAIL_FROM');
3212
3213 $trackid = 'mem'.$adherent->id;
3214 $moreinheader = 'X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
3215
3216 include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
3217 $cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), $cc, '', 0, 1, '', '', $trackid, $moreinheader);
3218 $result = $cmail->sendfile();
3219 if (!$result) {
3220 $error++;
3221 $this->error .= $cmail->error.' ';
3222 if (!is_null($cmail->errors)) {
3223 $this->errors += $cmail->errors;
3224 }
3225 $nbko++;
3226 $listofmembersko[$adherent->id] = $adherent->id;
3227 } else {
3228 $nbok++;
3229 $listofmembersok[$adherent->id] = $adherent->id;
3230
3231 $message = $msg;
3232 $sendto = $to;
3233 $sendtocc = '';
3234 $sendtobcc = '';
3235 $actioncode = 'EMAIL';
3236 $extraparams = array();
3237
3238 $actionmsg = '';
3239 $actionmsg2 = $langs->transnoentities('MailSentByTo', CMailFile::getValidAddress($from, 4, 0, 1), CMailFile::getValidAddress($sendto, 4, 0, 1));
3240 if ($message) {
3241 $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
3242 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
3243 if ($sendtocc) {
3244 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".dol_escape_htmltag($sendtocc));
3245 }
3246 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject);
3247 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":");
3248 $actionmsg = dol_concatdesc($actionmsg, $message);
3249 }
3250
3251 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
3252
3253 // Insert record of emails sent
3254 $actioncomm = new ActionComm($this->db);
3255
3256 $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
3257 $actioncomm->code = 'AC_'.$actioncode;
3258 $actioncomm->label = $actionmsg2;
3259 $actioncomm->note_private = $actionmsg;
3260 $actioncomm->fk_project = 0;
3261 $actioncomm->datep = $now;
3262 $actioncomm->datef = $now;
3263 $actioncomm->percentage = -1; // Not applicable
3264 $actioncomm->socid = (is_object($adherent->thirdparty) ? $adherent->thirdparty->id : 0);
3265 $actioncomm->contact_id = 0;
3266 $actioncomm->authorid = $user->id; // User saving action
3267 $actioncomm->userownerid = $user->id; // Owner of action
3268 // Fields when action is en email (content should be added into note)
3269 $actioncomm->email_msgid = $cmail->msgid;
3270 $actioncomm->email_from = $from;
3271 $actioncomm->email_sender = '';
3272 $actioncomm->email_to = $to;
3273 $actioncomm->email_tocc = $sendtocc;
3274 $actioncomm->email_tobcc = $sendtobcc;
3275 $actioncomm->email_subject = $subject;
3276 $actioncomm->errors_to = '';
3277
3278 $actioncomm->fk_element = $adherent->id;
3279 $actioncomm->elementid = $adherent->id;
3280 $actioncomm->elementtype = $adherent->element;
3281
3282 $actioncomm->extraparams = $extraparams;
3283
3284 $actioncomm->create($user);
3285 }
3286 } else {
3287 //$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
3288
3289 $error++;
3290 $this->error .= "Can't find email template with label=".$labeltouse.", to use for the reminding email ";
3291
3292 $nbko++;
3293 $listofmembersko[$adherent->id] = $adherent->id;
3294
3295 break;
3296 }
3297 }
3298
3299 $i++;
3300 }
3301 } else {
3302 $this->error = $this->db->lasterror();
3303 return 1;
3304 }
3305 }
3306
3307 if ($blockingerrormsg) {
3308 $this->error = $blockingerrormsg;
3309 return 1;
3310 } else {
3311 $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
3312 $this->output .= ' Send email successfully to '.$nbok.' members';
3313 if (is_array($listofmembersok)) {
3314 $listofids = '';
3315 $i = 0;
3316 foreach ($listofmembersok as $idmember) {
3317 if ($i > 100) {
3318 $listofids .= ', ...';
3319 break;
3320 }
3321 if (empty($listofids)) {
3322 $listofids .= ' [';
3323 } else {
3324 $listofids .= ', ';
3325 }
3326 $listofids .= $idmember;
3327 $i++;
3328 }
3329 if ($listofids) {
3330 $listofids .= ']';
3331 }
3332
3333 $this->output .= ($listofids ? ' ids='.$listofids : '');
3334 }
3335 if ($nbko) {
3336 $this->output .= ' - Canceled for '.$nbko.' member (no email or email sending error)';
3337 if (is_array($listofmembersko)) {
3338 $listofids = '';
3339 $i = 0;
3340 foreach ($listofmembersko as $idmember) {
3341 if ($i > 100) {
3342 $listofids .= ', ...';
3343 break;
3344 }
3345 if (empty($listofids)) {
3346 $listofids .= ' [';
3347 } else {
3348 $listofids .= ', ';
3349 }
3350 $listofids .= $idmember;
3351 $i++;
3352 }
3353 if ($listofids) {
3354 $listofids .= ']';
3355 }
3356 $this->output .= ($listofids ? ' ids='.$listofids : '');
3357 }
3358 }
3359 }
3360
3361 return $nbko;
3362 }
3363
3371 public function getKanbanView($option = '', $arraydata = null)
3372 {
3373 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
3374
3375 $return = '<div class="box-flex-item box-flex-grow-zero">';
3376 $return .= '<div class="info-box info-box-sm">';
3377 $return .= '<span class="info-box-icon bg-infobox-action">';
3378 if (property_exists($this, 'photo') || !empty($this->photo)) {
3379 $return .= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photowithmargin photologintooltip', 'small', 0, 1);
3380 } else {
3381 $return .= img_picto('', 'user');
3382 }
3383 $return .= '</span>';
3384 $return .= '<div class="info-box-content">';
3385 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
3386 if ($selected >= 0) {
3387 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
3388 }
3389 $return .= '<br><span class="info-box-label paddingright">'.$this->getmorphylib('', 2).'</span>';
3390 $return .= '<span class="info-box-label opacitymedium">'.$this->type.'</span>';
3391
3392 if (method_exists($this, 'getLibStatut')) {
3393 $return .= '<br><div class="info-box-status paddingtop">';
3394 $return .= $this->LibStatut($this->status, $this->need_subscription, $this->datefin, 5);
3395 $return .= '</div>';
3396 }
3397 $return .= '</div>';
3398 $return .= '</div>';
3399 $return .= '</div>';
3400 return $return;
3401 }
3402}
$object ref
Definition info.php:90
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.
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
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...
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|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158
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.