dolibarr 24.0.1
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-2026 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-2026 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
358 public $fields = array(
359 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
360 'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
361 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 15, 'index' => 1),
362 'ref_ext' => array('type' => 'varchar(128)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 20),
363 'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
364 'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
365 'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
366 'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => -1, 'position' => 40),
367 'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => 3, 'position' => 45),
368 'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => 3, 'position' => 50),
369 'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
370 'fk_adherent_type' => array('type' => 'integer', 'label' => 'MemberType', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
371 'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
372 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'LinkedToDolibarrThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
373 'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
374 'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
375 'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
376 'state_id' => array('type' => 'integer', 'label' => 'State', 'enabled' => 1, 'visible' => -1, 'position' => 90),
377 'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
378 'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
379 'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
380 'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
381 'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
382 'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
383 'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => 3, 'position' => 128),
384 'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
385 'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
386 'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
387 'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 145),
388 'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
389 'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
390 'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
391 'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
392 'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
393 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
394 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
395 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserCreation', 'enabled' => 1, 'visible' => 3, 'position' => 180),
396 'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModification', 'enabled' => 1, 'visible' => 3, 'position' => 185),
397 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => 3, 'position' => 190),
398 'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => 0, 'position' => 195),
399 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
400 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805),
401 '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'))
402 );
403
407 const STATUS_DRAFT = -1;
419 const STATUS_EXCLUDED = -2;
420
421
427 public function __construct($db)
428 {
429 $this->db = $db;
430 $this->statut = self::STATUS_DRAFT;
431 $this->status = self::STATUS_DRAFT;
432 // l'adherent n'est pas public par default
433 $this->public = 0;
434 $this->ismultientitymanaged = 1;
435 $this->isextrafieldmanaged = 1;
436 // Optional fields are empty
437 $this->array_options = array();
438
439 $this->fields['ref_ext']['visible'] = getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT');
440 }
441
442
443 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
462 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 = '')
463 {
464 // phpcs:enable
465 dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
466
467 return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
468 }
469
487 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 = '')
488 {
489 global $conf, $langs;
490
491 // Detect if message is HTML
492 if ($msgishtml == -1) {
493 $msgishtml = 0;
494 if (dol_textishtml($text, 0)) {
495 $msgishtml = 1;
496 }
497 }
498
499 dol_syslog('sendEmail msgishtml='.$msgishtml);
500
501 $texttosend = $this->makeSubstitution($text);
502 $subjecttosend = $this->makeSubstitution($subject);
503 if ($msgishtml) {
504 $texttosend = dol_htmlentitiesbr($texttosend);
505 }
506
507 // Send mail confirmation
508 $email_from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
509
510 $trackid = 'mem'.$this->id;
511
512 // Send email (substitutionarray must be done just before this)
513 include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
514 $mailfile = new CMailFile($subjecttosend, (string) $this->email, $email_from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
515 if ($mailfile->sendfile()) {
516 return 1;
517 } else {
518 $this->error = $langs->trans("ErrorFailedToSendMail", $email_from, (string) $this->email).'. '.$mailfile->error;
519 return -1;
520 }
521 }
522
523
530 public function makeSubstitution($text)
531 {
532 global $langs;
533
534 $birthday = dol_print_date($this->birth, 'day');
535 $photo = isset($this->photo) ? $this->photo : '';
536 $login = isset($this->login) ? $this->login : '';
537 $type = isset($this->type) ? $this->type : '';
538 $pass = isset($this->pass) ? $this->pass : '';
539
540 $msgishtml = 0;
541 if (dol_textishtml($text, 1)) {
542 $msgishtml = 1;
543 }
544
545 $infos = '';
546 if ($this->civility_id) {
547 $infos .= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
548 }
549 $infos .= $langs->transnoentities("Id").": ".$this->id."\n";
550 $infos .= $langs->transnoentities("Ref").": ".$this->ref."\n";
551 $infos .= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
552 $infos .= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
553 $infos .= $langs->transnoentities("Company").": ".$this->company."\n";
554 $infos .= $langs->transnoentities("Address").": ".$this->address."\n";
555 $infos .= $langs->transnoentities("Zip").": ".$this->zip."\n";
556 $infos .= $langs->transnoentities("Town").": ".$this->town."\n";
557 $infos .= $langs->transnoentities("Country").": ".$this->country."\n";
558 $infos .= $langs->transnoentities("EMail").": ".$this->email."\n";
559 $infos .= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
560 $infos .= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
561 $infos .= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
562 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
563 $infos .= $langs->transnoentities("Login").": ".$login."\n";
564 $infos .= $langs->transnoentities("Password").": ".$pass."\n";
565 }
566 $infos .= $langs->transnoentities("Birthday").": ".$birthday."\n";
567 $infos .= $langs->transnoentities("Photo").": ".$photo."\n";
568 $infos .= $langs->transnoentities("Public").": ".yn($this->public);
569
570 // Substitutions
571 $substitutionarray = array(
572 '__ID__' => $this->id,
573 '__REF__' => $this->ref,
574 '__MEMBER_ID__' => $this->id,
575 '__CIVILITY__' => $this->getCivilityLabel(),
576 '__FIRSTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->firstname) : ($this->firstname ? $this->firstname : ''),
577 '__LASTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->lastname) : ($this->lastname ? $this->lastname : ''),
578 '__FULLNAME__' => $msgishtml ? dol_htmlentitiesbr($this->getFullName($langs)) : $this->getFullName($langs),
579 '__COMPANY__' => $msgishtml ? dol_htmlentitiesbr((string) $this->company) : ($this->company ? $this->company : ''),
580 '__ADDRESS__' => $msgishtml ? dol_htmlentitiesbr((string) $this->address) : ($this->address ? $this->address : ''),
581 '__ZIP__' => $msgishtml ? dol_htmlentitiesbr((string) $this->zip) : ($this->zip ? $this->zip : ''),
582 '__TOWN__' => $msgishtml ? dol_htmlentitiesbr((string) $this->town) : ($this->town ? $this->town : ''),
583 '__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''),
584 '__EMAIL__' => $msgishtml ? dol_htmlentitiesbr((string) $this->email) : ($this->email ? $this->email : ''),
585 '__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''),
586 '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($photo) : $photo,
587 '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($login) : $login,
588 '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($pass) : $pass,
589 '__PHONE__' => $msgishtml ? dol_htmlentitiesbr($this->phone) : ($this->phone ? $this->phone : ''),
590 '__PHONEPRO__' => $msgishtml ? dol_htmlentitiesbr($this->phone_perso) : ($this->phone_perso ? $this->phone_perso : ''),
591 '__PHONEMOBILE__' => $msgishtml ? dol_htmlentitiesbr($this->phone_mobile) : ($this->phone_mobile ? $this->phone_mobile : ''),
592 '__TYPE__' => $msgishtml ? dol_htmlentitiesbr($type) : $type,
593 );
594
595 complete_substitutions_array($substitutionarray, $langs, $this);
596
597 return make_substitutions($text, $substitutionarray, $langs);
598 }
599
600
608 public function getmorphylib($morphy = '', $addbadge = 0)
609 {
610 global $langs;
611 $s = '';
612
613 // Clean var
614 if (!$morphy) {
615 $morphy = $this->morphy;
616 }
617
618 if ($addbadge) {
619 $labeltoshowm = $langs->trans("Moral");
620 $labeltoshowp = $langs->trans("Physical");
621 if ($morphy == 'phy') {
622 $labeltoshow = $labeltoshowp;
623 if ($addbadge == 2) {
624 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp));
625 if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowm))) {
626 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp, 2));
627 }
628 }
629 $s .= '<span class="member-individual-back paddingleftimp paddingrightimp" title="'.$langs->trans("Physical").'">'.$labeltoshow.'</span>';
630 }
631 if ($morphy == 'mor') {
632 $labeltoshow = $labeltoshowm;
633 if ($addbadge == 2) {
634 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm));
635 if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowp))) {
636 $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm, 2));
637 }
638 }
639 $s .= '<span class="member-company-back paddingleftimp paddingrightimp" title="'.$langs->trans("Moral").'">'.$labeltoshow.'</span>';
640 }
641 } else {
642 if ($morphy == 'phy') {
643 $s = $langs->trans("Physical");
644 } elseif ($morphy == 'mor') {
645 $s = $langs->trans("Moral");
646 }
647 }
648
649 return $s;
650 }
651
659 public function create($user, $notrigger = 0)
660 {
661 global $langs, $mysoc;
662
663 $error = 0;
664
665 $now = dol_now();
666
667 // Clean parameters
668 if (isset($this->import_key)) {
669 $this->import_key = trim($this->import_key);
670 }
671
672 // Check parameters
673 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail((string) $this->email)) {
674 $langs->load("errors");
675 $this->error = $langs->trans("ErrorBadEMail", (string) $this->email);
676 return -1;
677 }
678 if (!$this->datec) {
679 $this->datec = $now;
680 }
681 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
682 if (empty($this->login)) {
683 $this->error = $langs->trans("ErrorWrongValueForParameterX", "Login");
684 return -1;
685 }
686 }
687
688 // setEntity will set entity with the right value if empty or change it for the right value if multicompany module is active
689 $this->entity = setEntity($this);
690
691 $this->db->begin();
692
693 // Insert member
694 $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
695 $sql .= " (ref, datec, login, fk_user_author, fk_user_mod, fk_user_valid, morphy, fk_adherent_type, entity, import_key, ip)";
696 $sql .= " VALUES (";
697 $sql .= " '(PROV)'";
698 $sql .= ", '".$this->db->idate($this->datec)."'";
699 $sql .= ", ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
700 $sql .= ", ".($user->id > 0 ? ((int) $user->id) : "null"); // Can be null because member can be created by a guest or a script
701 $sql .= ", null, null, '".$this->db->escape($this->morphy)."'";
702 $sql .= ", ".((int) $this->typeid);
703 $sql .= ", ".((int) $this->entity);
704 $sql .= ", ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
705 $sql .= ", ".(!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
706 $sql .= ")";
707
708 dol_syslog(get_class($this)."::create", LOG_DEBUG);
709 $result = $this->db->query($sql);
710 if ($result) {
711 $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
712 if ($id > 0) {
713 $this->id = $id;
714
715 $modulenum = getDolGlobalString('MEMBER_CODEMEMBER_ADDON', 'mod_member_simple');
716
717 $modfile = dol_buildpath('core/modules/member/'.$modulenum.'.php', 0);
718 try {
719 require_once $modfile;
720 $modname = $modulenum;
721 $modCodeMember = new $modname();
722 '@phan-var-force ModeleNumRefMembers $modCodeMember';
724 $this->ref = $modCodeMember->getNextValue($mysoc, $this);
725 } catch (Exception $e) {
726 dol_syslog($e->getMessage(), LOG_ERR);
727 $error++;
728 }
729
730 // Update minor fields
731 $result = $this->update($user, 1, 1, 0, 0, 'add'); // nosync is 1 to avoid update data of user
732 if ($result < 0) {
733 $this->db->rollback();
734 return -1;
735 }
736
737 // Add link to user
738 if ($this->user_id) {
739 // Add link to user
740 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
741 $sql .= " fk_member = ".((int) $this->id);
742 $sql .= " WHERE rowid = ".((int) $this->user_id);
743 dol_syslog(get_class($this)."::create", LOG_DEBUG);
744 $resql = $this->db->query($sql);
745 if (!$resql) {
746 $this->error = 'Failed to update user to make link with member';
747 $this->db->rollback();
748 return -4;
749 }
750 }
751
752 if (!$notrigger) {
753 // Call trigger
754 $result = $this->call_trigger('MEMBER_CREATE', $user);
755 if ($result < 0) {
756 $error++;
757 }
758 // End call triggers
759 }
760
761 if (count($this->errors)) {
762 dol_syslog(get_class($this)."::create ".implode(',', $this->errors), LOG_ERR);
763 $this->db->rollback();
764 return -3;
765 } else {
766 $this->db->commit();
767 return $this->id;
768 }
769 } else {
770 $this->error = 'Failed to get last insert id';
771 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
772 $this->db->rollback();
773 return -2;
774 }
775 } else {
776 $this->error = $this->db->error();
777 $this->db->rollback();
778 return -1;
779 }
780 }
781
782
794 public function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
795 {
796 global $langs, $hookmanager;
797
798 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
799
800 if (empty($this->country_id) && !empty($this->country_code)) {
801 $country_id = getCountry($this->country_code, '3');
802 $this->country_id = is_int($country_id) ? $country_id : 0;
803 }
804
805 $nbrowsaffected = 0;
806 $error = 0;
807
808 dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
809
810 // Clean parameters
811 $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
812 $this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
813 // civility_code is the reference property. Fall back to the deprecated civility_id alias only when civility_code was not set by the caller.
814 if (empty($this->civility_code) && !empty($this->civility_id)) {
815 $this->civility_code = $this->civility_id;
816 }
817 if (isset($this->gender)) {
818 $this->gender = trim($this->gender);
819 }
820 // $this->address = ($this->address ? $this->address : $this->address);
821 // $this->zip = ($this->zip ? $this->zip : $this->zip);
822 // $this->town = ($this->town ? $this->town : $this->town);
823 // $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
824 // $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id);
825 // $this->note_public = ($this->note_public ? $this->note_public : $this->note_public);
826 // $this->note_private = ($this->note_private ? $this->note_private : $this->note_private);
827 $this->url = $this->url ? clean_url($this->url, 0) : '';
828 $this->setUpperOrLowerCase();
829
830 // Check parameters
831 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail((string) $this->email)) {
832 $langs->load("errors");
833 $this->error = $langs->trans("ErrorBadEMail", (string) $this->email);
834 return -1;
835 }
836
837 $this->db->begin();
838
839 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
840 $sql .= " ref = '".$this->db->escape($this->ref)."'";
841 $sql .= ", ref_ext = ".(empty($this->ref_ext) ? "null" : "'".$this->db->escape($this->ref_ext)."'");
842 $sql .= ", civility = ".($this->civility_code ? "'".$this->db->escape($this->civility_code)."'" : "null");
843 $sql .= ", firstname = ".($this->firstname ? "'".$this->db->escape($this->firstname)."'" : "null");
844 $sql .= ", lastname = ".($this->lastname ? "'".$this->db->escape($this->lastname)."'" : "null");
845 $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
846 $sql .= ", login = ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
847 $sql .= ", societe = ".($this->company ? "'".$this->db->escape($this->company)."'" : ($this->societe ? "'".$this->db->escape($this->societe)."'" : "null"));
848 if ($this->socid) {
849 $sql .= ", fk_soc = ".($this->socid > 0 ? (int) $this->socid : "null"); // Must be modified only when creating from a third-party
850 }
851 $sql .= ", address = ".($this->address ? "'".$this->db->escape($this->address)."'" : "null");
852 $sql .= ", zip = ".($this->zip ? "'".$this->db->escape($this->zip)."'" : "null");
853 $sql .= ", town = ".($this->town ? "'".$this->db->escape($this->town)."'" : "null");
854 $sql .= ", country = ".($this->country_id > 0 ? (int) $this->country_id : "null");
855 $sql .= ", state_id = ".($this->state_id > 0 ? (int) $this->state_id : "null");
856 $sql .= ", email = '".$this->db->escape((string) $this->email)."'";
857 $sql .= ", url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
858 $sql .= ", socialnetworks = ".($this->socialnetworks ? "'".$this->db->escape(json_encode($this->socialnetworks))."'" : "null");
859 $sql .= ", phone = ".($this->phone ? "'".$this->db->escape($this->phone)."'" : "null");
860 $sql .= ", phone_perso = ".($this->phone_perso ? "'".$this->db->escape($this->phone_perso)."'" : "null");
861 $sql .= ", phone_mobile = ".($this->phone_mobile ? "'".$this->db->escape($this->phone_mobile)."'" : "null");
862 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
863 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
864 $sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
865 $sql .= ", public = ".(int) $this->public;
866 $sql .= ", statut = ".(int) $this->statut;
867 $sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
868 $sql .= ", fk_adherent_type = ".(int) $this->typeid;
869 $sql .= ", morphy = '".$this->db->escape($this->morphy)."'";
870 $sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null");
871
872 if ($this->datefin) {
873 $sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
874 }
875 if ($this->datevalid) {
876 $sql .= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
877 }
878 $sql .= ", fk_user_mod = ".($user->id > 0 ? ((int) $user->id) : 'null'); // Can be null because member can be create by a guest
879 $sql .= " WHERE rowid = ".((int) $this->id);
880
881 // If we change the type of membership, we set also label of new type..
882 '@phan-var-force Adherent $oldcopy';
883 if (!empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid) {
884 $sql2 = "SELECT libelle as label";
885 $sql2 .= " FROM ".MAIN_DB_PREFIX."adherent_type";
886 $sql2 .= " WHERE rowid = ".((int) $this->typeid);
887 $resql2 = $this->db->query($sql2);
888 if ($resql2) {
889 while ($obj = $this->db->fetch_object($resql2)) {
890 $this->type = $obj->label;
891 }
892 }
893 }
894
895 dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
896 $resql = $this->db->query($sql);
897 if ($resql) {
898 unset($this->country_code);
899 unset($this->country);
900 unset($this->state_code);
901 unset($this->state);
902
903 $nbrowsaffected += $this->db->affected_rows($resql);
904
905 $action = 'update';
906
907 // Actions on extra fields
908 $result = $this->insertExtraFields();
909 if ($result < 0) {
910 $error++;
911 }
912
913 // Update password
914 if (!$error && $this->pass) {
915 dol_syslog(get_class($this)."::update update password");
916 if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) {
917 $isencrypted = getDolGlobalString('DATABASE_PWD_ENCRYPTED') ? 1 : 0;
918
919 // If password to set differs from the one found into database
920 $result = $this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
921 if (!$nbrowsaffected) {
922 $nbrowsaffected++;
923 }
924 }
925 }
926
927 // Remove links to user and replace with new one
928 if (!$error) {
929 dol_syslog(get_class($this)."::update update link to user");
930 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
931 dol_syslog(get_class($this)."::update", LOG_DEBUG);
932 $resql = $this->db->query($sql);
933 if (!$resql) {
934 $this->error = $this->db->error();
935 $this->db->rollback();
936 return -5;
937 }
938 // If there is a user linked to this member
939 if ($this->user_id > 0) {
940 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id)." WHERE rowid = ".((int) $this->user_id);
941 dol_syslog(get_class($this)."::update", LOG_DEBUG);
942 $resql = $this->db->query($sql);
943 if (!$resql) {
944 $this->error = $this->db->error();
945 $this->db->rollback();
946 return -5;
947 }
948 }
949 }
950
951 if (!$error && $nbrowsaffected) { // If something has change in main data
952 // Update information on linked user if it is an update
953 if ($this->user_id > 0 && !$nosyncuser) {
954 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
955
956 dol_syslog(get_class($this)."::update update linked user");
957
958 $luser = new User($this->db);
959 $result = $luser->fetch($this->user_id);
960
961 if ($result >= 0) {
962 // 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.
963 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
964 $luser->login = $this->login;
965 }
966
967 $luser->ref = $this->ref;
968 $luser->civility_code = $this->civility_code;
969 $luser->firstname = $this->firstname;
970 $luser->lastname = $this->lastname;
971 $luser->gender = $this->gender;
972 $luser->pass = isset($this->pass) ? $this->pass : '';
973 //$luser->socid=$this->fk_soc; // We do not enable this. This may transform a user into an external user.
974
975 $luser->birth = $this->birth;
976
977 $luser->address = $this->address;
978 $luser->zip = $this->zip;
979 $luser->town = $this->town;
980 $luser->country_id = $this->country_id;
981 $luser->state_id = $this->state_id;
982
983 $luser->email = $this->email;
984 $luser->socialnetworks = $this->socialnetworks;
985 $luser->office_phone = $this->phone;
986 $luser->user_mobile = $this->phone_mobile;
987
988 $luser->lang = $this->default_lang;
989
990 $luser->fk_member = $this->id;
991
992 $result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
993 if ($result < 0) {
994 $this->error = $luser->error;
995 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
996 $error++;
997 }
998 } else {
999 $this->error = $luser->error;
1000 $error++;
1001 }
1002 }
1003
1004 // Update information on linked thirdparty if it is an update
1005 if (!$error && $this->socid > 0 && !$nosyncthirdparty) {
1006 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1007
1008 dol_syslog(get_class($this)."::update update linked thirdparty");
1009
1010 // This member is linked with a thirdparty, so we also update thirdparty information
1011 // if this is an update.
1012 $lthirdparty = new Societe($this->db);
1013 $result = $lthirdparty->fetch($this->socid);
1014
1015 if ($result > 0) {
1016 $lthirdparty->address = $this->address;
1017 $lthirdparty->zip = $this->zip;
1018 $lthirdparty->town = $this->town;
1019 $lthirdparty->email = $this->email;
1020 $lthirdparty->socialnetworks = $this->socialnetworks;
1021 $lthirdparty->phone = $this->phone;
1022 $lthirdparty->state_id = $this->state_id;
1023 $lthirdparty->country_id = $this->country_id;
1024 //$lthirdparty->phone_mobile=$this->phone_mobile;
1025 $lthirdparty->default_lang = $this->default_lang;
1026
1027 $result = $lthirdparty->update($this->socid, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
1028
1029 if ($result < 0) {
1030 $this->error = $lthirdparty->error;
1031 $this->errors = $lthirdparty->errors;
1032 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
1033 $error++;
1034 }
1035 } elseif ($result < 0) {
1036 $this->error = $lthirdparty->error;
1037 $error++;
1038 }
1039 }
1040 }
1041
1042 if (!$error && !$notrigger) {
1043 // Call trigger
1044 $result = $this->call_trigger('MEMBER_MODIFY', $user);
1045 if ($result < 0) {
1046 $error++;
1047 }
1048 // End call triggers
1049 }
1050
1051 if (!$error) {
1052 $this->db->commit();
1053 return $nbrowsaffected;
1054 } else {
1055 $this->db->rollback();
1056 return -1;
1057 }
1058 } else {
1059 $this->db->rollback();
1060 $this->error = $this->db->lasterror();
1061 return -2;
1062 }
1063 }
1064
1065
1066 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1074 public function update_end_date($user)
1075 {
1076 // phpcs:enable
1077 $this->db->begin();
1078
1079 // Search for last subscription id and end date
1080 $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
1081 $sql .= " FROM ".MAIN_DB_PREFIX."subscription";
1082 $sql .= " WHERE fk_adherent = ".((int) $this->id);
1083 $sql .= " ORDER by dateadh DESC"; // Sort by start subscription date
1084
1085 dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1086 $resql = $this->db->query($sql);
1087 if ($resql) {
1088 $obj = $this->db->fetch_object($resql);
1089 $dateop = $this->db->jdate($obj->dateop);
1090 $datedeb = $this->db->jdate($obj->datedeb);
1091 $datefin = $this->db->jdate($obj->datefin);
1092
1093 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1094 $sql .= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
1095 $sql .= " WHERE rowid = ".((int) $this->id);
1096
1097 dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
1098 $resql = $this->db->query($sql);
1099 if ($resql) {
1100 $this->last_subscription_date = $dateop;
1101 $this->last_subscription_date_start = $datedeb;
1102 $this->last_subscription_date_end = $datefin;
1103 $this->datefin = $datefin;
1104 $this->db->commit();
1105 return 1;
1106 } else {
1107 $this->db->rollback();
1108 return -1;
1109 }
1110 } else {
1111 $this->error = $this->db->lasterror();
1112 $this->db->rollback();
1113 return -1;
1114 }
1115 }
1116
1124 public function delete($user, $notrigger = 0)
1125 {
1126 $result = 0;
1127 $error = 0;
1128 $errorflag = 0;
1129
1130 // Check parameters
1131 $rowid = $this->id;
1132
1133 $this->db->begin();
1134
1135 if (!$notrigger) {
1136 // Call trigger
1137 $result = $this->call_trigger('MEMBER_DELETE', $user);
1138 if ($result < 0) {
1139 $error++;
1140 }
1141 // End call triggers
1142 }
1143
1144 // Remove category
1145 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".((int) $rowid);
1146 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1147 $resql = $this->db->query($sql);
1148 if (!$resql) {
1149 $error++;
1150 $this->error .= $this->db->lasterror();
1151 $errorflag = -1;
1152 }
1153
1154 // Remove subscription
1155 if (!$error) {
1156 $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".((int) $rowid);
1157 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1158 $resql = $this->db->query($sql);
1159 if (!$resql) {
1160 $error++;
1161 $this->error .= $this->db->lasterror();
1162 $errorflag = -2;
1163 }
1164 }
1165
1166 // Remove linked user
1167 if (!$error) {
1168 $ret = $this->setUserId(0);
1169 if ($ret < 0) {
1170 $error++;
1171 $this->error .= $this->db->lasterror();
1172 $errorflag = -3;
1173 }
1174 }
1175
1176 // Removed extrafields
1177 if (!$error) {
1178 $result = $this->deleteExtraFields();
1179 if ($result < 0) {
1180 $error++;
1181 $errorflag = -4;
1182 dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
1183 }
1184 }
1185
1186 // Remove adherent
1187 if (!$error) {
1188 $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".((int) $rowid);
1189 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1190 $resql = $this->db->query($sql);
1191 if (!$resql) {
1192 $error++;
1193 $this->error .= $this->db->lasterror();
1194 $errorflag = -5;
1195 }
1196 }
1197
1198 if (!$error) {
1199 $this->db->commit();
1200 return 1;
1201 } else {
1202 $this->db->rollback();
1203 return $errorflag;
1204 }
1205 }
1206
1217 public function mergeMembers($member_origin_id)
1218 {
1219 global $conf, $langs, $hookmanager, $user, $action;
1220
1221 $error = 0;
1222 $member_origin = new Adherent($this->db); // The member that we will delete
1223
1224 dol_syslog("mergeMembers merge member id=".$member_origin_id." (will be deleted) into the member id=".$this->id);
1225 if ($member_origin->fetch($member_origin_id) < 1) {
1226 $this->error = $langs->trans('ErrorRecordNotFound');
1227 $error++;
1228 }
1229
1230 if (!$error) {
1231 $this->db->begin();
1232 $listofproperties = array(
1233 'ref_ext', 'civility', 'lastname', 'firstname', 'morphy', 'societe', 'socid', 'user_id','address',
1234 'zip', 'town', 'state_id', 'country', 'phone', 'phone_perso', 'phone_mobile', 'email',
1235 'url', 'socialnetworks', 'birth', 'gender', 'photo', 'public', 'datefin', 'default_lang',
1236 'canvas', 'model_pdf', 'import_key'
1237 );
1238 foreach ($listofproperties as $property) {
1239 if (empty($this->$property)) {
1240 $this->$property = $member_origin->$property;
1241 }
1242 }
1243
1244 // Concat some data
1245 $listofproperties = array(
1246 'note_public', 'note_private'
1247 );
1248 foreach ($listofproperties as $property) {
1249 $this->$property = dol_concatdesc($this->$property, $member_origin->$property);
1250 }
1251
1252 // Merge extrafields
1253 if (is_array($member_origin->array_options)) {
1254 foreach ($member_origin->array_options as $key => $val) {
1255 if (empty($this->array_options[$key])) {
1256 $this->array_options[$key] = $val;
1257 }
1258 }
1259 }
1260
1261 // Merge categories
1262 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1263 $static_cat = new Categorie($this->db);
1264 $custcats_ori = $static_cat->containing($member_origin->id, 'member', 'id');
1265 $custcats = $static_cat->containing($this->id, 'member', 'id');
1266 $custcats = array_merge($custcats, $custcats_ori);
1267 $this->setCategories($custcats);
1268
1269 $result = $this->update($user, 1, 1, 1, 1, 'merge');
1270 if ($result < 0) {
1271 $error++;
1272 }
1273
1274 // Merge subscriptions
1275 if (!$error && $member_origin->fetch_subscriptions() < 1) {
1276 $error++;
1277 }
1278
1279 if (!$error) {
1280 foreach ($member_origin->subscriptions as $key => $subscription) {
1281 $subscription->fk_adherent = $this->id;
1282 $result = $subscription->update($user);
1283 if ($result < 0) {
1284 $error++;
1285 break;
1286 }
1287 }
1288 }
1289
1290 // External modules should update their ones too
1291 if (!$error) {
1292 $parameters = array('member_origin' => $member_origin->id, 'member_dest' => $this->id);
1293 $reshook = $hookmanager->executeHooks('replaceMember', $parameters, $this, $action);
1294
1295 if ($reshook < 0) {
1296 $this->setErrorsFromObject($hookmanager);
1297 $error++;
1298 }
1299 }
1300
1301 if (!$error) {
1302 $this->context = array('merge' => 1, 'mergefromid' => $member_origin->id);
1303
1304 // Call trigger
1305 $result = $this->call_trigger('MEMBER_MODIFY', $user);
1306 if ($result < 0) {
1307 $error++;
1308 }
1309 // End call triggers
1310 }
1311
1312 if (!$error) {
1313 // We finally remove the old member
1314 if ($member_origin->delete($user) < 1) {
1315 $this->setErrorsFromObject($member_origin);
1316 $error++;
1317 }
1318 }
1319
1320 if (!$error) {
1321 // Move files from the dir of the third party to delete into the dir of the third party to keep
1322 if (!empty($conf->adherent->multidir_output[$this->entity])) {
1323 $srcdir = $conf->adherent->multidir_output[$this->entity]."/".$member_origin->id;
1324 $destdir = $conf->adherent->multidir_output[$this->entity]."/".$this->id;
1325
1326 if (dol_is_dir($srcdir)) {
1327 $dirlist = dol_dir_list($srcdir, 'files', 1);
1328 foreach ($dirlist as $filetomove) {
1329 $destfile = $destdir.'/'.$filetomove['relativename'];
1330 $result = dol_move($filetomove['fullname'], $destfile, '0', 0, 0, 1);
1331 if (!$result) {
1332 $error++;
1333 }
1334 }
1335 }
1336 }
1337 }
1338
1339 if (!$error) {
1340 $this->db->commit();
1341 return 0;
1342 } else {
1343 $langs->load("errors");
1344 $this->error = $langs->trans('ErrorMembersMerge');
1345 $this->db->rollback();
1346 return -1;
1347 }
1348 }
1349 return -1;
1350 }
1351
1362 public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
1363 {
1364 global $conf, $langs;
1365
1366 $error = 0;
1367
1368 dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." isencrypted=".$isencrypted);
1369
1370 // If new password not provided, we generate one
1371 if (!$password) {
1372 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
1373 $password = getRandomPassword(false);
1374 }
1375
1376 // Crypt password
1377 $password_crypted = dol_hash($password);
1378
1379 $password_indatabase = '';
1380 if (!$isencrypted) {
1381 $password_indatabase = $password;
1382 }
1383
1384 $this->db->begin();
1385
1386 // Mise a jour
1387 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
1388 $sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
1389 if ($isencrypted) {
1390 $sql .= ", pass = null";
1391 } else {
1392 $sql .= ", pass = '".$this->db->escape($password_indatabase)."'";
1393 }
1394 $sql .= " WHERE rowid = ".((int) $this->id);
1395
1396 //dol_syslog("Adherent::Password sql=hidden");
1397 dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1398 $result = $this->db->query($sql);
1399 if ($result) {
1400 $nbaffectedrows = $this->db->affected_rows($result);
1401
1402 if ($nbaffectedrows) {
1403 $this->pass = $password;
1404 $this->pass_indatabase = $password_indatabase;
1405 $this->pass_indatabase_crypted = $password_crypted;
1406
1407 if ($this->user_id && !$nosyncuser) {
1408 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1409
1410 // This member is linked with a user, so we also update users information
1411 // if this is an update.
1412 $luser = new User($this->db);
1413 $result = $luser->fetch($this->user_id);
1414
1415 if ($result >= 0) {
1416 $result = $luser->setPassword($user, $this->pass, 0, 0, 1);
1417 if (is_int($result) && $result < 0) {
1418 $this->error = $luser->error;
1419 dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR);
1420 $error++;
1421 }
1422 } else {
1423 $this->error = $luser->error;
1424 $error++;
1425 }
1426 }
1427
1428 if (!$error && !$notrigger) {
1429 // Call trigger
1430 $result = $this->call_trigger('MEMBER_NEW_PASSWORD', $user);
1431 if ($result < 0) {
1432 $error++;
1433 $this->db->rollback();
1434 return -1;
1435 }
1436 // End call triggers
1437 }
1438
1439 $this->db->commit();
1440 return $this->pass;
1441 } else {
1442 $this->db->rollback();
1443 return 0;
1444 }
1445 } else {
1446 $this->db->rollback();
1447 dol_print_error($this->db);
1448 return -1;
1449 }
1450 }
1451
1452
1459 public function setUserId($userid)
1460 {
1461 global $conf, $langs;
1462
1463 $this->db->begin();
1464
1465 // If user is linked to this member, remove old link to this member
1466 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
1467 dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1468 $resql = $this->db->query($sql);
1469 if (!$resql) {
1470 $this->error = $this->db->error();
1471 $this->db->rollback();
1472 return -1;
1473 }
1474
1475 // Set link to user
1476 if ($userid > 0) {
1477 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id);
1478 $sql .= " WHERE rowid = ".((int) $userid);
1479 dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1480 $resql = $this->db->query($sql);
1481 if (!$resql) {
1482 $this->error = $this->db->error();
1483 $this->db->rollback();
1484 return -2;
1485 }
1486 }
1487
1488 $this->db->commit();
1489
1490 return 1;
1491 }
1492
1493
1500 public function setThirdPartyId($thirdpartyid)
1501 {
1502 global $conf, $langs;
1503
1504 $this->db->begin();
1505
1506 // Remove link to third party onto any other members
1507 if ($thirdpartyid > 0) {
1508 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
1509 $sql .= " WHERE fk_soc = ".((int) $thirdpartyid);
1510 $sql .= " AND entity = ".((int) $conf->entity);
1511 dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1512 $resql = $this->db->query($sql);
1513 }
1514
1515 // Add link to third party for current member
1516 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid > 0 ? (int) $thirdpartyid : 'null');
1517 $sql .= " WHERE rowid = ".((int) $this->id);
1518
1519 dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1520 $resql = $this->db->query($sql);
1521 if ($resql) {
1522 $this->db->commit();
1523 return 1;
1524 } else {
1525 $this->error = $this->db->error();
1526 $this->db->rollback();
1527 return -1;
1528 }
1529 }
1530
1531
1532 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1539 public function fetch_login($login)
1540 {
1541 // phpcs:enable
1542 global $conf;
1543
1544 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1545 $sql .= " WHERE login='".$this->db->escape($login)."'";
1546 $sql .= " AND entity = ".((int) $conf->entity);
1547
1548 $resql = $this->db->query($sql);
1549 if ($resql) {
1550 if ($this->db->num_rows($resql)) {
1551 $obj = $this->db->fetch_object($resql);
1552 $this->fetch($obj->rowid);
1553 }
1554 } else {
1555 dol_print_error($this->db);
1556 }
1557 }
1558
1559 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1567 public function fetch_name($firstname, $lastname)
1568 {
1569 // phpcs:enable
1570 global $conf;
1571
1572 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1573 $sql .= " WHERE firstname='".$this->db->escape($firstname)."'";
1574 $sql .= " AND lastname='".$this->db->escape($lastname)."'";
1575 $sql .= " AND entity = ".((int) $conf->entity);
1576
1577 $resql = $this->db->query($sql);
1578 if ($resql) {
1579 if ($this->db->num_rows($resql)) {
1580 $obj = $this->db->fetch_object($resql);
1581 $this->fetch($obj->rowid);
1582 }
1583 } else {
1584 dol_print_error($this->db);
1585 }
1586 }
1587
1599 public function fetch($rowid, $ref = '', $socid = 0, $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
1600 {
1601 global $langs;
1602
1603 $sql = "SELECT d.rowid, d.ref, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname,";
1604 $sql .= " d.societe as company, d.fk_soc as socid, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1605 $sql .= " d.note_public,";
1606 $sql .= " d.email, d.url, d.socialnetworks, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1607 $sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1608 $sql .= " d.datec as datec,";
1609 $sql .= " GREATEST(d.tms, aef.tms) as datem,";
1610 $sql .= " d.datefin as datefin, d.default_lang,";
1611 $sql .= " d.birth as birthday,";
1612 $sql .= " d.datevalid as datev,";
1613 $sql .= " d.country,";
1614 $sql .= " d.state_id,";
1615 $sql .= " d.model_pdf,";
1616 $sql .= " c.rowid as country_id, c.code as country_code, c.label as country,";
1617 $sql .= " dep.nom as state, dep.code_departement as state_code,";
1618 $sql .= " t.libelle as type, t.subscription as subscription,";
1619 $sql .= " u.rowid as user_id, u.login as user_login";
1620 $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
1621 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'adherent_extrafields as aef ON aef.fk_object = d.rowid';
1622 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
1623 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
1624 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
1625 $sql .= " WHERE d.fk_adherent_type = t.rowid";
1626 if ($rowid) {
1627 $sql .= " AND d.rowid=".((int) $rowid);
1628 } elseif ($ref || $socid) {
1629 $sql .= " AND d.entity IN (".getEntity('adherent').")";
1630 if ($ref) {
1631 $sql .= " AND d.ref='".$this->db->escape($ref)."'";
1632 } elseif ($socid > 0) {
1633 $sql .= " AND d.fk_soc=".((int) $socid);
1634 }
1635 } elseif ($ref_ext) {
1636 $sql .= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
1637 }
1638
1639 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1640 $resql = $this->db->query($sql);
1641 if ($resql) {
1642 if ($this->db->num_rows($resql)) {
1643 $obj = $this->db->fetch_object($resql);
1644
1645 $this->entity = $obj->entity;
1646 $this->id = $obj->rowid;
1647 $this->ref = $obj->ref;
1648 $this->ref_ext = $obj->ref_ext;
1649
1650 $this->civility_id = $obj->civility_code; // Bad. Kept for backward compatibility
1651 $this->civility_code = $obj->civility_code;
1652 $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : '';
1653
1654 $this->firstname = $obj->firstname;
1655 $this->lastname = $obj->lastname;
1656 $this->gender = $obj->gender;
1657 $this->login = $obj->login;
1658 $this->societe = $obj->company;
1659 $this->company = $obj->company;
1660 $this->socid = $obj->socid;
1661 $this->fk_soc = $obj->socid; // For backward compatibility
1662 $this->address = $obj->address;
1663 $this->zip = $obj->zip;
1664 $this->town = $obj->town;
1665
1666 $this->pass = $obj->pass;
1667 $this->pass_indatabase = $obj->pass;
1668 $this->pass_indatabase_crypted = $obj->pass_crypted;
1669
1670 $this->state_id = $obj->state_id;
1671 $this->state_code = $obj->state_id ? $obj->state_code : '';
1672 $this->state = $obj->state_id ? $obj->state : '';
1673
1674 $this->country_id = $obj->country_id;
1675 $this->country_code = $obj->country_code;
1676 if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) {
1677 $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
1678 } else {
1679 $this->country = $obj->country;
1680 }
1681
1682 $this->phone = $obj->phone;
1683 $this->phone_perso = $obj->phone_perso;
1684 $this->phone_mobile = $obj->phone_mobile;
1685 $this->email = $obj->email;
1686 $this->url = $obj->url;
1687
1688 $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1689
1690 $this->photo = $obj->photo;
1691 $this->statut = $obj->statut;
1692 $this->status = $obj->statut;
1693 $this->public = $obj->public;
1694
1695 $this->datec = $this->db->jdate($obj->datec);
1696 $this->date_creation = $this->db->jdate($obj->datec);
1697 $this->datem = $this->db->jdate($obj->datem);
1698 $this->date_modification = $this->db->jdate($obj->datem);
1699 $this->datefin = $this->db->jdate($obj->datefin);
1700 $this->datevalid = $this->db->jdate($obj->datev);
1701 $this->date_validation = $this->db->jdate($obj->datev);
1702 $this->birth = $this->db->jdate($obj->birthday);
1703
1704 $this->default_lang = $obj->default_lang;
1705
1706 $this->note_private = $obj->note_private;
1707 $this->note_public = $obj->note_public;
1708 $this->morphy = $obj->morphy;
1709
1710 $this->typeid = $obj->fk_adherent_type;
1711 $this->type = $obj->type;
1712 $this->need_subscription = $obj->subscription;
1713
1714 $this->user_id = $obj->user_id;
1715 $this->user_login = $obj->user_login;
1716
1717 $this->model_pdf = $obj->model_pdf;
1718
1719 // Retrieve all extrafield
1720 // fetch optionals attributes and labels
1721 if ($fetch_optionals) {
1722 $this->fetch_optionals();
1723 }
1724
1725 // Load other properties
1726 if ($fetch_subscriptions) {
1727 $result = $this->fetch_subscriptions();
1728 }
1729
1730 return $this->id;
1731 } else {
1732 return 0;
1733 }
1734 } else {
1735 $this->error = $this->db->lasterror();
1736 return -1;
1737 }
1738 }
1739
1740
1741 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1750 public function fetch_subscriptions()
1751 {
1752 // phpcs:enable
1753 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1754
1755 $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
1756 $sql .= " c.tms as datem,";
1757 $sql .= " c.datec as datec,";
1758 $sql .= " c.dateadh as dateh,";
1759 $sql .= " c.datef as datef";
1760 $sql .= " FROM ".MAIN_DB_PREFIX."subscription as c";
1761 $sql .= " WHERE c.fk_adherent = ".((int) $this->id);
1762 $sql .= " ORDER BY c.dateadh";
1763 dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
1764
1765 $resql = $this->db->query($sql);
1766 if ($resql) {
1767 $this->subscriptions = array();
1768
1769 $i = 0;
1770 while ($obj = $this->db->fetch_object($resql)) {
1771 if ($i == 0) {
1772 $this->first_subscription_date = $this->db->jdate($obj->datec);
1773 $this->first_subscription_date_start = $this->db->jdate($obj->dateh);
1774 $this->first_subscription_date_end = $this->db->jdate($obj->datef);
1775 $this->first_subscription_amount = $obj->subscription;
1776 }
1777 $this->last_subscription_date = $this->db->jdate($obj->datec);
1778 $this->last_subscription_date_start = $this->db->jdate($obj->dateh);
1779 $this->last_subscription_date_end = $this->db->jdate($obj->datef);
1780 $this->last_subscription_amount = (float) $obj->subscription;
1781
1782 $subscription = new Subscription($this->db);
1783 $subscription->id = $obj->rowid;
1784 $subscription->fk_adherent = $obj->fk_adherent;
1785 $subscription->fk_type = $obj->fk_type;
1786 $subscription->amount = (float) $obj->subscription;
1787 $subscription->note = $obj->note_public;
1788 $subscription->note_public = $obj->note_public;
1789 $subscription->fk_bank = $obj->fk_bank;
1790 $subscription->datem = $this->db->jdate($obj->datem);
1791 $subscription->datec = $this->db->jdate($obj->datec);
1792 $subscription->dateh = $this->db->jdate($obj->dateh);
1793 $subscription->datef = $this->db->jdate($obj->datef);
1794
1795 $this->subscriptions[] = $subscription;
1796
1797 $i++;
1798 }
1799 return 1;
1800 } else {
1801 $this->error = $this->db->error().' sql='.$sql;
1802 return -1;
1803 }
1804 }
1805
1806
1813 public function fetchPartnerships($mode)
1814 {
1815 require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php';
1816
1817
1818 $this->partnerships[] = array();
1819
1820 return 1;
1821 }
1822
1823
1840 public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null, $ref_ext = '')
1841 {
1842 global $user;
1843
1844 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1845
1846 $error = 0;
1847
1848 // Clean parameters
1849 if (!$amount) {
1850 $amount = 0;
1851 }
1852
1853 $this->db->begin();
1854
1855 if ($datesubend) {
1856 $datefin = $datesubend;
1857 } else {
1858 // If no end date, end date = date + 1 year - 1 day
1859 $datefin = dol_time_plus_duree($date, 1, 'y');
1860 $datefin = dol_time_plus_duree($datefin, -1, 'd');
1861 }
1862
1863 // Create subscription
1864 $subscription = new Subscription($this->db);
1865 $subscription->fk_adherent = $this->id;
1866 $subscription->dateh = $date; // Date of new subscription
1867 $subscription->datef = $datefin; // End data of new subscription
1868 $subscription->amount = $amount;
1869 $subscription->note_public = $label;
1870 $subscription->note_private = '';
1871 $subscription->fk_type = $fk_type;
1872 $subscription->ref_ext = $ref_ext;
1873
1874 if (empty($subscription->user_creation_id)) {
1875 $subscription->user_creation_id = $user->id;
1876 }
1877
1878 $rowid = $subscription->create($user);
1879 if ($rowid > 0) {
1880 // Update denormalized subscription end date (read database subscription to find values)
1881 // This will also update this->datefin
1882 $result = $this->update_end_date($user);
1883 if ($result > 0) {
1884 // Change properties of object (used by triggers)
1885 $this->last_subscription_date = dol_now();
1886 $this->last_subscription_date_start = $date;
1887 $this->last_subscription_date_end = $datefin;
1888 $this->last_subscription_amount = $amount;
1889 } else {
1890 $error++;
1891 }
1892
1893 if (!$error) {
1894 $this->db->commit();
1895 return $rowid;
1896 } else {
1897 $this->db->rollback();
1898 return -2;
1899 }
1900 } else {
1901 $this->setErrorsFromObject($subscription);
1902 $this->db->rollback();
1903 return -1;
1904 }
1905 }
1906
1907
1927 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 = '')
1928 {
1929 global $conf, $langs, $user, $mysoc;
1930
1931 $error = 0;
1932
1933 $this->invoice = null; // This will contains invoice if an invoice is created
1934
1935 dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".
1936 $paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
1937
1938 // Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
1939 if ($option == 'bankdirect' && $accountid) {
1940 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1941
1942 $acct = new Account($this->db);
1943 $result = $acct->fetch($accountid);
1944
1945 $dateop = $paymentdate;
1946
1947 $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, 0, $user, $emetteur_nom, $emetteur_banque);
1948 if ($insertid > 0) {
1949 $inserturlid = $acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
1950 if ($inserturlid > 0) {
1951 // Update table subscription
1952 $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".((int) $insertid);
1953 $sql .= " WHERE rowid=".((int) $subscriptionid);
1954
1955 dol_syslog("subscription::subscription", LOG_DEBUG);
1956 $resql = $this->db->query($sql);
1957 if (!$resql) {
1958 $error++;
1959 $this->error = $this->db->lasterror();
1960 $this->errors[] = $this->error;
1961 }
1962 } else {
1963 $error++;
1964 $this->setErrorsFromObject($acct);
1965 }
1966 } else {
1967 $error++;
1968 $this->setErrorsFromObject($acct);
1969 }
1970 }
1971
1972 // If option chosen, we create invoice
1973 if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
1974 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1975 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
1976
1977 $invoice = new Facture($this->db);
1978 $customer = new Societe($this->db);
1979
1980 if (!$error) {
1981 if (!($this->socid > 0)) { // If not yet linked to a company
1982 if ($autocreatethirdparty) {
1983 // Create a linked thirdparty to member
1984 $companyalias = '';
1985 $fullname = $this->getFullName($langs);
1986
1987 if ($this->morphy == 'mor') {
1988 $companyname = $this->company;
1989 if (!empty($fullname)) {
1990 $companyalias = $fullname;
1991 }
1992 } else {
1993 $companyname = $fullname;
1994 if (!empty($this->company)) {
1995 $companyalias = $this->company;
1996 }
1997 }
1998
1999 $result = $customer->create_from_member($this, (string) $companyname, $companyalias);
2000 if ($result < 0) {
2001 $this->error = $customer->error;
2002 $this->errors = $customer->errors;
2003 $error++;
2004 } else {
2005 $this->fk_soc = $result;
2006 $this->socid = $result;
2007 }
2008 } else {
2009 $langs->load("errors");
2010 $this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
2011 $this->errors[] = $this->error;
2012 $error++;
2013 }
2014 }
2015 }
2016 if (!$error) {
2017 $result = $customer->fetch($this->socid);
2018 if ($result <= 0) {
2019 $this->error = $customer->error;
2020 $this->errors = $customer->errors;
2021 $error++;
2022 }
2023 }
2024
2025 if (!$error) {
2026 // Create draft invoice
2027 $invoice->type = Facture::TYPE_STANDARD;
2028 $invoice->cond_reglement_id = $customer->cond_reglement_id;
2029 if (empty($invoice->cond_reglement_id)) {
2030 $paymenttermstatic = new PaymentTerm($this->db);
2031 $invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
2032 if (empty($invoice->cond_reglement_id)) {
2033 $error++;
2034 $this->error = 'ErrorNoPaymentTermRECEPFound';
2035 $this->errors[] = $this->error;
2036 }
2037 }
2038 $invoice->socid = $this->socid;
2039 // set customer's payment bank account on the invoice
2040 if (!empty($customer->fk_account)) {
2041 $invoice->fk_account = $customer->fk_account;
2042 } elseif (getDolGlobalString('FACTURE_RIB_NUMBER')) {
2043 // set default bank account from invoice module settings
2044 $invoice->fk_account = (int) getDolGlobalString('FACTURE_RIB_NUMBER');
2045 }
2046 //set customer's payment method on the invoice
2047 if (!empty($customer->mode_reglement_id)) {
2048 $invoice->mode_reglement_id = $customer->mode_reglement_id;
2049 }
2050 //$invoice->date = $datesubscription;
2051 $invoice->date = dol_now();
2052
2053 // Possibility to add external linked objects with hooks
2054 $invoice->linked_objects['subscription'] = $subscriptionid;
2055 if (GETPOSTISARRAY('other_linked_objects')) {
2056 $invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int'));
2057 }
2058
2059 $result = $invoice->create($user);
2060 if ($result <= 0) {
2061 $this->setErrorsFromObject($invoice);
2062 $error++;
2063 } else {
2064 $this->invoice = $invoice;
2065 }
2066 }
2067
2068 if (!$error) {
2069 // Add line to draft invoice
2070 $idprodsubscription = 0;
2071 if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
2072 $idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
2073 }
2074
2075 $vattouse = 0;
2076 if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
2077 $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
2078 }
2079 //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
2080 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2081 $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, 0, 'TTC', $amount, 1);
2082 if ($result <= 0) {
2083 $this->setErrorsFromObject($invoice);
2084 $error++;
2085 }
2086 }
2087
2088 if (!$error) {
2089 // Validate invoice
2090 $result = $invoice->validate($user);
2091 if ($result <= 0) {
2092 $this->setErrorsFromObject($invoice);
2093 $error++;
2094 }
2095 }
2096
2097 if (!$error) {
2098 // TODO Link invoice with subscription ?
2099 }
2100
2101 // Add payment onto invoice
2102 if (!$error && $option == 'bankviainvoice' && $accountid) {
2103 require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
2104 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
2105 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
2106
2107 $amounts = array();
2108 $amounts[$invoice->id] = (float) price2num($amount);
2109
2110 $paiement = new Paiement($this->db);
2111 $paiement->datepaye = $paymentdate;
2112 $paiement->amounts = $amounts;
2113 $paiement->paiementcode = $operation;
2114 $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
2115 $paiement->num_payment = $num_chq;
2116 $paiement->note_public = $label;
2117 $paiement->ext_payment_id = $ext_payment_id;
2118 $paiement->ext_payment_site = $ext_payment_site;
2119
2120 // Create payment line for invoice
2121 $paiement_id = $paiement->create($user);
2122 if (!($paiement_id > 0)) {
2123 $this->setErrorsFromObject($paiement);
2124 $error++;
2125 }
2126
2127 if (!$error) {
2128 // Add transaction into bank account
2129 $bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
2130 if (!($bank_line_id > 0)) {
2131 $this->setErrorsFromObject($paiement);
2132 $error++;
2133 }
2134 }
2135
2136 if (!$error && !empty($bank_line_id)) {
2137 // Update fk_bank into subscription table
2138 $sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.((int) $bank_line_id);
2139 $sql .= ' WHERE rowid='.((int) $subscriptionid);
2140
2141 $result = $this->db->query($sql);
2142 if (!$result) {
2143 $error++;
2144 }
2145 }
2146
2147 if (!$error) {
2148 // Set invoice as paid
2149 $invoice->setPaid($user);
2150 }
2151 }
2152
2153 if (!$error) {
2154 // Define output language
2155 $outputlangs = $langs;
2156 $newlang = '';
2157 $lang_id = GETPOST('lang_id');
2158 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
2159 $newlang = $lang_id;
2160 }
2161 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
2162 $newlang = $customer->default_lang;
2163 }
2164 if (!empty($newlang)) {
2165 $outputlangs = new Translate("", $conf);
2166 $outputlangs->setDefaultLang($newlang);
2167 }
2168 // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
2169 //if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
2170
2171 $invoice->fetch($invoice->id); // Reload invoice object data
2172 $invoice->generateDocument($invoice->model_pdf, $outputlangs);
2173 }
2174 }
2175
2176 if ($error) {
2177 return -1;
2178 } else {
2179 return 1;
2180 }
2181 }
2182
2183
2191 public function validate($user, $notrigger = 0)
2192 {
2193 global $langs, $conf;
2194
2195 $error = 0;
2196 $now = dol_now();
2197
2198 // Check parameters
2199 if ($this->status == self::STATUS_VALIDATED) {
2200 dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
2201 return 0;
2202 }
2203
2204 $this->db->begin();
2205
2206 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2207 $sql .= " statut = ".self::STATUS_VALIDATED;
2208 $sql .= ", datevalid = '".$this->db->idate($now)."'";
2209 $sql .= ", fk_user_valid = ".((int) $user->id);
2210 $sql .= " WHERE rowid = ".((int) $this->id);
2211
2212 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
2213 $result = $this->db->query($sql);
2214 if ($result) {
2215 $this->statut = self::STATUS_VALIDATED;
2217
2218 // Call trigger
2219 if (!$notrigger) {
2220 $result = $this->call_trigger('MEMBER_VALIDATE', $user);
2221 if ($result < 0) {
2222 $error++;
2223 $this->db->rollback();
2224 return -1;
2225 }
2226 }
2227 // End call triggers
2228
2229 $this->datevalid = $now;
2230
2231 $this->db->commit();
2232 return 1;
2233 } else {
2234 $this->error = $this->db->error();
2235 $this->db->rollback();
2236 return -1;
2237 }
2238 }
2239
2240
2247 public function resiliate($user)
2248 {
2249 global $langs, $conf;
2250
2251 $error = 0;
2252
2253 // Check parameters
2254 if ($this->status == self::STATUS_RESILIATED) {
2255 dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2256 return 0;
2257 }
2258
2259 $this->db->begin();
2260
2261 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2262 $sql .= " statut = ".((int) self::STATUS_RESILIATED);
2263 $sql .= ", fk_user_valid = ".((int) $user->id);
2264 $sql .= " WHERE rowid = ".((int) $this->id);
2265
2266 $result = $this->db->query($sql);
2267 if ($result) {
2268 $this->statut = self::STATUS_RESILIATED;
2270
2271 // Call trigger
2272 $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2273 if ($result < 0) {
2274 $error++;
2275 $this->db->rollback();
2276 return -1;
2277 }
2278 // End call triggers
2279
2280 $this->db->commit();
2281 return 1;
2282 } else {
2283 $this->error = $this->db->error();
2284 $this->db->rollback();
2285 return -1;
2286 }
2287 }
2288
2298 public function exclude($user)
2299 {
2300 $error = 0;
2301
2302 // Check parameters
2303 if ($this->status == self::STATUS_EXCLUDED) {
2304 dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
2305 return 0;
2306 }
2307
2308 $this->db->begin();
2309
2310 $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
2311 $sql .= " statut = ".((int) self::STATUS_EXCLUDED);
2312 $sql .= ", fk_user_valid = ".((int) $user->id);
2313 $sql .= " WHERE rowid = ".((int) $this->id);
2314
2315 $result = $this->db->query($sql);
2316 if ($result) {
2317 $this->statut = self::STATUS_EXCLUDED;
2319
2320 // Call trigger
2321 $result = $this->call_trigger('MEMBER_EXCLUDE', $user);
2322 if ($result < 0) {
2323 $error++;
2324 $this->db->rollback();
2325 return -1;
2326 }
2327 // End call triggers
2328
2329 $this->db->commit();
2330 return 1;
2331 } else {
2332 $this->error = $this->db->error();
2333 $this->db->rollback();
2334 return -1;
2335 }
2336 }
2337
2338 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2344 public function add_to_abo()
2345 {
2346 // phpcs:enable
2347 global $langs;
2348
2349 include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2350 $mailmanspip = new MailmanSpip($this->db);
2351
2352 $err = 0;
2353
2354 // mailman
2355 if (getDolGlobalString('ADHERENT_USE_MAILMAN') && isModEnabled('mailmanspip')) {
2356 $result = $mailmanspip->add_to_mailman($this);
2357
2358 if ($result < 0) {
2359 if (!empty($mailmanspip->error)) {
2360 $this->errors[] = $mailmanspip->error;
2361 }
2362 $err += 1;
2363 }
2364 foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) {
2365 $langs->load("errors");
2366 $this->errors[] = $langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
2367 }
2368 foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) {
2369 $langs->load("mailmanspip");
2370 $this->mesgs[] = $langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
2371 }
2372 }
2373
2374 // spip
2375 if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2376 $result = $mailmanspip->add_to_spip($this);
2377 if ($result < 0) {
2378 $this->errors[] = $mailmanspip->error;
2379 $err += 1;
2380 }
2381 }
2382 if ($err) {
2383 return -$err;
2384 } else {
2385 return 1;
2386 }
2387 }
2388
2389
2390 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2396 public function del_to_abo()
2397 {
2398 // phpcs:enable
2399 global $conf, $langs;
2400
2401 include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
2402 $mailmanspip = new MailmanSpip($this->db);
2403
2404 $err = 0;
2405
2406 // mailman
2407 if (getDolGlobalString('ADHERENT_USE_MAILMAN')) {
2408 $result = $mailmanspip->del_to_mailman($this);
2409 if ($result < 0) {
2410 if (!empty($mailmanspip->error)) {
2411 $this->errors[] = $mailmanspip->error;
2412 }
2413 $err += 1;
2414 }
2415
2416 foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) {
2417 $langs->load("errors");
2418 $this->errors[] = $langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
2419 }
2420 foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) {
2421 $langs->load("mailmanspip");
2422 $this->mesgs[] = $langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
2423 }
2424 }
2425
2426 if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2427 $result = $mailmanspip->del_to_spip($this);
2428 if ($result < 0) {
2429 $this->errors[] = $mailmanspip->error;
2430 $err += 1;
2431 }
2432 }
2433 if ($err) {
2434 // error
2435 return -$err;
2436 } else {
2437 return 1;
2438 }
2439 }
2440
2441
2447 public function getCivilityLabel()
2448 {
2449 global $langs;
2450 $langs->load("dict");
2451
2452 $code = (empty($this->civility_id) ? '' : $this->civility_id);
2453 if (empty($code)) {
2454 return '';
2455 }
2456 return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
2457 }
2458
2465 public function getTooltipContentArray($params)
2466 {
2467 global $langs;
2468
2469 $langs->loadLangs(['members', 'companies']);
2470 $nofetch = !empty($params['nofetch']);
2471
2472 $datas = array();
2473
2474 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2475 $langs->load("users");
2476 return ['optimize' => $langs->trans("ShowUser")];
2477 }
2478 if (!empty($this->photo)) {
2479 $photo = '<div class="photointooltip floatright">';
2480 $photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1);
2481 $photo .= '</div>';
2482 $datas['photo'] = $photo;
2483 }
2484
2485 $datas['divopen'] = '<div class="centpercent">';
2486 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Member").'</u> '.$this->getLibStatut(4);
2487 if (!empty($this->morphy)) {
2488 $datas['picto'] .= '&nbsp;' . $this->getmorphylib('', 1);
2489 }
2490 if (!empty($this->ref)) {
2491 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
2492 }
2493 if (!empty($this->login)) {
2494 $datas['login'] = '<br><b>'.$langs->trans('Login').':</b> '.$this->login;
2495 }
2496 if (!empty($this->firstname) || !empty($this->lastname)) {
2497 $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
2498 }
2499 if (!empty($this->company)) {
2500 $datas['company'] = '<br><b>'.$langs->trans('Company').':</b> '.$this->company;
2501 }
2502 if (!empty($this->email)) {
2503 $datas['email'] = '<br><b>'.$langs->trans("EMail").':</b> '.$this->email;
2504 }
2505 $datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs);
2506 // show categories for this record only in ajax to not overload lists
2507 if (isModEnabled('category') && !$nofetch) {
2508 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
2509 $form = new Form($this->db);
2510 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_MEMBER, 1);
2511 }
2512 $datas['divclose'] = '</div>';
2513
2514 return $datas;
2515 }
2516
2530 public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0)
2531 {
2532 global $langs, $hookmanager;
2533
2534 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpictoimg) {
2535 $withpictoimg = 0;
2536 }
2537
2538 $result = '';
2539 $linkstart = '';
2540 $linkend = '';
2541 $classfortooltip = 'classfortooltip';
2542 $dataparams = '';
2543 $params = [
2544 'id' => $this->id,
2545 'objecttype' => $this->element,
2546 'option' => $option,
2547 'nofetch' => 1,
2548 ];
2549 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
2550 $classfortooltip = 'classforajaxtooltip';
2551 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
2552 $label = '';
2553 } else {
2554 $label = implode($this->getTooltipContentArray($params));
2555 }
2556
2557 $baseurl = DOL_URL_ROOT . '/adherents/card.php';
2558 if ($option == 'subscription') {
2559 $baseurl = DOL_URL_ROOT . '/adherents/subscription.php';
2560 }
2561 $query = ['rowid' => $this->id];
2562
2563 if ($option != 'nolink') {
2564 // Add param to save lastsearch_values or not
2565 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2566 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
2567 $add_save_lastsearch_values = 1;
2568 }
2569 if ($add_save_lastsearch_values) {
2570 $query = array_merge($query, ['save_lastsearch_values' => 1]);
2571 }
2572 }
2573 $url = dolBuildUrl($baseurl, $query);
2574
2575 $linkstart .= '<a href="'.$url.'"';
2576 $linkclose = "";
2577 if (empty($notooltip)) {
2578 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2579 $langs->load("users");
2580 $label = $langs->trans("ShowUser");
2581 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
2582 }
2583 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
2584 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
2585 }
2586
2587 $linkstart .= $linkclose.'>';
2588 $linkend = '</a>';
2589
2590 $result .= $linkstart;
2591
2592 if ($withpictoimg) {
2593 if (abs($withpictoimg) == 1 || abs($withpictoimg) == 4) {
2594 $morecss .= ' paddingrightonly';
2595 }
2596 // Only picto
2597 if ($withpictoimg > 0) {
2598 $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">'.img_object('', 'user', ' '.($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1).'</span>';
2599 } else {
2600 // Picto must be a photo
2601 $picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">';
2602 $picto .= Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.(($withpictoimg == -3 || $withpictoimg == -4) ? 'small' : ''), 'mini', 0, 1);
2603 $picto .= '</span>';
2604 }
2605 $result .= $picto;
2606 }
2607 if (($withpictoimg > -2 && $withpictoimg != 2) || $withpictoimg == -4) {
2608 if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2609 $result .= '<span class="nopadding valignmiddle'.((!isset($this->status) || $this->status) ? '' : ' strikefordisabled').
2610 ($morecss ? ' usertext'.$morecss : '').'">';
2611 }
2612 if ($mode == 'login') {
2613 $result .= dol_trunc(isset($this->login) ? $this->login : '', $maxlen);
2614 } elseif ($mode == 'ref') {
2615 $result .= $this->ref;
2616 } else {
2617 if (empty($this->lastname) && empty($this->firstname) && !empty($this->company)) {
2618 $result .= $this->company;
2619 } else {
2620 $result .= $this->getFullName($langs, 0, ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2621 }
2622 }
2623 if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2624 $result .= '</span>';
2625 }
2626 }
2627
2628 $result .= $linkend;
2629
2630 if ($addlinktonotes) {
2631 if ($this->note_private) {
2632 $notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($this->note_private, 1);
2633 $result .= ' <span class="note inline-block">';
2634 $result .= '<a href="'.DOL_URL_ROOT.'/adherents/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
2635 $result .= img_picto('', 'note');
2636 $result .= '</a>';
2637 $result .= '</span>';
2638 }
2639 }
2640 global $action;
2641 $hookmanager->initHooks(array($this->element . 'dao'));
2642 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
2643 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2644 if ($reshook > 0) {
2645 $result = $hookmanager->resPrint;
2646 } else {
2647 $result .= $hookmanager->resPrint;
2648 }
2649 return $result;
2650 }
2651
2658 public function getLibStatut($mode = 0)
2659 {
2660 return $this->LibStatut($this->status, $this->need_subscription, $this->datefin, $mode);
2661 }
2662
2663 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2673 public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
2674 {
2675 // phpcs:enable
2676 global $langs;
2677 $langs->load("members");
2678
2679 $statusType = '';
2680 $labelStatus = '';
2681 $labelStatusShort = '';
2682
2683 if ($status == self::STATUS_DRAFT) {
2684 $statusType = 'status0';
2685 $labelStatus = $langs->trans("MemberStatusDraft");
2686 $labelStatusShort = $langs->trans("MemberStatusDraftShort");
2687 } elseif ($status >= self::STATUS_VALIDATED) {
2688 if ($need_subscription === 0) {
2689 $statusType = 'status4';
2690 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusNoSubscription");
2691 $labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
2692 } elseif (!$date_end_subscription) {
2693 $statusType = 'status1';
2694 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("WaitingSubscription");
2695 $labelStatusShort = $langs->trans("WaitingSubscriptionShort");
2696 } elseif ($date_end_subscription < dol_now()) { // expired
2697 $statusType = 'status2';
2698 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusActiveLate");
2699 $labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
2700 } else {
2701 $statusType = 'status4';
2702 $labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusPaid");
2703 $labelStatusShort = $langs->trans("MemberStatusPaidShort");
2704 }
2705 } elseif ($status == self::STATUS_RESILIATED) {
2706 $statusType = 'status6';
2707 $labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
2708 $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
2709 } elseif ($status == self::STATUS_EXCLUDED) {
2710 $statusType = 'status10';
2711 $labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
2712 $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
2713 }
2714
2715 return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
2716 }
2717
2718
2724 public function loadStateBoard()
2725 {
2726 global $conf;
2727
2728 $this->nb = array();
2729
2730 $sql = "SELECT count(a.rowid) as nb";
2731 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2732 $sql .= " WHERE a.statut > 0";
2733 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2734
2735 $resql = $this->db->query($sql);
2736 if ($resql) {
2737 while ($obj = $this->db->fetch_object($resql)) {
2738 $this->nb["members"] = $obj->nb;
2739 }
2740 $this->db->free($resql);
2741 return 1;
2742 } else {
2743 dol_print_error($this->db);
2744 $this->error = $this->db->error();
2745 return -1;
2746 }
2747 }
2748
2749 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2757 public function load_board($user, $mode)
2758 {
2759 // phpcs:enable
2760 global $conf, $langs;
2761
2762 if ($user->socid) {
2763 return -1; // Protection to prevent calls by external users
2764 }
2765
2766 $now = dol_now();
2767
2768 $sql = "SELECT a.rowid, a.datefin, a.statut as status";
2769 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
2770 $sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
2771 $sql .= " WHERE a.fk_adherent_type = t.rowid";
2772 if ($mode == 'expired') {
2773 $sql .= " AND a.statut = ".self::STATUS_VALIDATED;
2774 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2775 $sql .= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = '1')";
2776 } elseif ($mode == 'shift') {
2777 $sql .= " AND a.statut = ".self::STATUS_DRAFT;
2778 $sql .= " AND a.entity IN (".getEntity('adherent').")";
2779 }
2780
2781 $resql = $this->db->query($sql);
2782 if ($resql) {
2783 $langs->load("members");
2784
2785 $warning_delay = 0;
2786 $url = '';
2787 $label = '';
2788 $labelShort = '';
2789
2790 if ($mode == 'expired') {
2791 $warning_delay = getWarningDelay('member', 'subscription') / 60 / 60 / 24;
2792 $label = $langs->trans("MembersWithSubscriptionToReceive");
2793 $labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
2794 $url = dolBuildUrl(DOL_URL_ROOT.'/adherents/list.php', ['mainmenu' => 'members', 'statut' => self::STATUS_VALIDATED, 'filter' => 'outofdate']);
2795 } elseif ($mode == 'shift') {
2796 $warning_delay = getWarningDelay('member', 'subscription') / 60 / 60 / 24;
2797 $url = dolBuildUrl(DOL_URL_ROOT.'/adherents/list.php', ['mainmenu' => 'members', 'statut' => self::STATUS_DRAFT]);
2798 $label = $langs->trans("MembersListToValid");
2799 $labelShort = $langs->trans("ToValidate");
2800 }
2801
2802 $response = new WorkboardResponse();
2803 $response->warning_delay = $warning_delay;
2804 $response->label = $label;
2805 $response->labelShort = $labelShort;
2806 $response->url = $url;
2807 $response->img = img_object('', "user");
2808
2809 $adherentstatic = new Adherent($this->db);
2810
2811 while ($obj = $this->db->fetch_object($resql)) {
2812 $response->nbtodo++;
2813
2814 $adherentstatic->datefin = $this->db->jdate($obj->datefin);
2815 $adherentstatic->statut = $obj->status;
2816 $adherentstatic->status = $obj->status;
2817
2818 if ($adherentstatic->hasDelay()) {
2819 $response->nbtodolate++;
2820 }
2821 }
2822
2823 return $response;
2824 } else {
2825 dol_print_error($this->db);
2826 $this->error = $this->db->error();
2827 return -1;
2828 }
2829 }
2830
2831
2843 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2844 {
2845 global $conf, $langs;
2846
2847 $langs->load("orders");
2848
2849 if (!dol_strlen($modele)) {
2850 $modele = 'standard';
2851
2852 if ($this->model_pdf) {
2853 $modele = $this->model_pdf;
2854 } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2855 $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2856 }
2857 }
2858
2859 $modelpath = "core/modules/member/doc/";
2860
2861 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2862 }
2863
2864
2872 public function initAsSpecimen()
2873 {
2874 global $user, $langs;
2875 $now = dol_now();
2876
2877 // Initialise parameters
2878 $this->id = 0;
2879 $this->ref = 'ABC001';
2880 $this->entity = 1;
2881 $this->specimen = 1;
2882 $this->civility_id = 'MR';
2883 $this->lastname = 'DOLIBARR';
2884 $this->firstname = 'SPECIMEN';
2885 $this->gender = 'man';
2886 $this->login = 'dolibspec';
2887 $this->pass = 'dolibspec';
2888 $this->company = 'Societe ABC';
2889 $this->address = '61 jump street';
2890 $this->zip = '75000';
2891 $this->town = 'Paris';
2892 $this->country_id = 1;
2893 $this->country_code = 'FR';
2894 $this->country = 'France';
2895 $this->morphy = 'mor';
2896 $this->email = 'specimen@specimen.com';
2897 $this->socialnetworks = array(
2898 'skype' => 'skypepseudo',
2899 'twitter' => 'twitterpseudo',
2900 'facebook' => 'facebookpseudo',
2901 'linkedin' => 'linkedinpseudo',
2902 );
2903 $this->phone = '0999999999';
2904 $this->phone_perso = '0999999998';
2905 $this->phone_mobile = '0999999997';
2906 $this->note_public = 'This is a public note';
2907 $this->note_private = 'This is a private note';
2908 $this->birth = $now;
2909 $this->photo = '';
2910 $this->public = 1;
2911 $this->statut = self::STATUS_DRAFT;
2912 $this->status = self::STATUS_DRAFT;
2913
2914 $this->datefin = $now;
2915 $this->datevalid = $now;
2916 $this->default_lang = '';
2917
2918 $this->typeid = 1; // Id type adherent
2919 $this->type = 'Type adherent'; // Libelle type adherent
2920 $this->need_subscription = 0;
2921
2922 $this->first_subscription_date = $now;
2923 $this->first_subscription_date_start = $this->first_subscription_date;
2924 $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2925 $this->first_subscription_amount = 10;
2926
2927 $this->last_subscription_date = $this->first_subscription_date;
2928 $this->last_subscription_date_start = $this->first_subscription_date;
2929 $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2930 $this->last_subscription_amount = 10;
2931 return 1;
2932 }
2933
2934
2935 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2936 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2946 public function _load_ldap_dn($info, $mode = 0)
2947 {
2948 // phpcs:enable
2949 global $conf;
2950 $dn = '';
2951 if ($mode == 0) {
2952 $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')]."," . getDolGlobalString('LDAP_MEMBER_DN');
2953 }
2954 if ($mode == 1) {
2955 $dn = getDolGlobalString('LDAP_MEMBER_DN');
2956 }
2957 if ($mode == 2) {
2958 $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')];
2959 }
2960 return $dn;
2961 }
2962
2963
2964 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2965 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2971 public function _load_ldap_info()
2972 {
2973 // phpcs:enable
2974 global $conf, $langs;
2975
2976 $info = array();
2977 $socialnetworks = getArrayOfSocialNetworks();
2978 $keymodified = false;
2979
2980 // Object classes
2981 $info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
2982
2983 $this->fullname = $this->getFullName($langs);
2984
2985 // For avoid ldap error when firstname and lastname are empty
2986 if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
2987 $this->fullname = $this->company;
2988 $this->lastname = $this->company;
2989 }
2990
2991 // Possible LDAP KEY (constname => varname)
2992 $ldapkey = array(
2993 'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
2994 'LDAP_MEMBER_FIELD_NAME' => 'lastname',
2995 'LDAP_MEMBER_FIELD_LOGIN' => 'login',
2996 'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
2997 'LDAP_MEMBER_FIELD_MAIL' => 'email'
2998 );
2999
3000 // Member
3001 foreach ($ldapkey as $constname => $varname) {
3002 if (!empty($this->$varname) && getDolGlobalString($constname)) {
3003 $info[getDolGlobalString($constname)] = $this->$varname;
3004
3005 // Check if it is the LDAP key and if its value has been changed
3006 if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
3007 if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
3008 $keymodified = true; // For check if LDAP key has been modified
3009 }
3010 }
3011 }
3012 }
3013 if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
3014 $info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
3015 }
3016 if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
3017 $info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
3018 }
3019 if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
3020 $info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
3021 }
3022 if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
3023 $info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
3024 }
3025 if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
3026 $info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
3027 }
3028 if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
3029 $info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
3030 }
3031 if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
3032 $info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
3033 }
3034 foreach ($socialnetworks as $key => $value) {
3035 if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))) {
3036 $info[getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
3037 }
3038 }
3039 if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
3040 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
3041 }
3042 if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
3043 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
3044 }
3045 if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
3046 $info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
3047 }
3048 if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
3049 $info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
3050 }
3051 if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
3052 $info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
3053 }
3054 if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
3055 $info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
3056 }
3057 if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
3058 $info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
3059 }
3060 if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
3061 $info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
3062 }
3063 if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
3064 $info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
3065 }
3066
3067 // When password is modified
3068 if (!empty($this->pass)) {
3069 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
3070 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
3071 }
3072 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
3073 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
3074 }
3075 } elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
3076 // Set LDAP password if possible
3077 // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
3078 if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
3079 // Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
3080 if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
3081 if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
3082 // Create OpenLDAP MD5 password from Dolibarr MD5 password
3083 // Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
3084 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
3085 }
3086 }
3087 } elseif (!empty($this->pass_indatabase)) {
3088 // Use $this->pass_indatabase value if exists
3089 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
3090 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
3091 }
3092 if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
3093 $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
3094 }
3095 }
3096 }
3097
3098 // Subscriptions
3099 if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
3100 $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
3101 }
3102 if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
3103 $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
3104 }
3105 if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
3106 $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
3107 }
3108 if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
3109 $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
3110 }
3111
3112 return $info;
3113 }
3114
3115
3122 public function info($id)
3123 {
3124 $sql = 'SELECT a.rowid, a.datec as datec,';
3125 $sql .= ' a.datevalid as datev,';
3126 $sql .= ' GREATEST(a.tms, aef.tms) as datem,';
3127 $sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
3128 $sql .= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
3129 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'adherent_extrafields as aef ON aef.fk_object = a.rowid';
3130 $sql .= ' WHERE a.rowid = '.((int) $id);
3131
3132 dol_syslog(get_class($this)."::info", LOG_DEBUG);
3133 $result = $this->db->query($sql);
3134 if ($result) {
3135 if ($this->db->num_rows($result)) {
3136 $obj = $this->db->fetch_object($result);
3137
3138 $this->id = $obj->rowid;
3139
3140 $this->user_creation_id = $obj->fk_user_author;
3141 $this->user_validation_id = $obj->fk_user_valid;
3142 $this->user_modification_id = $obj->fk_user_mod;
3143 $this->date_creation = $this->db->jdate($obj->datec);
3144 $this->date_validation = $this->db->jdate($obj->datev);
3145 $this->date_modification = $this->db->jdate($obj->datem);
3146 }
3147
3148 $this->db->free($result);
3149 } else {
3150 dol_print_error($this->db);
3151 }
3152 }
3153
3159 public function getNbOfEMailings()
3160 {
3161 $sql = "SELECT count(mc.email) as nb";
3162 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
3163 $sql .= " WHERE mc.email = '".$this->db->escape($this->email)."'";
3164 $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 error, 0 not sent, 1 sent with success
3165
3166 $resql = $this->db->query($sql);
3167 if ($resql) {
3168 $obj = $this->db->fetch_object($resql);
3169 $nb = (int) $obj->nb;
3170
3171 $this->db->free($resql);
3172 return $nb;
3173 } else {
3174 $this->error = $this->db->error();
3175 return -1;
3176 }
3177 }
3178
3189 public function setCategories($categories)
3190 {
3191 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
3192 return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
3193 }
3194
3203 public static function replaceThirdparty($db, $origin_id, $dest_id)
3204 {
3205 $tables = array('adherent');
3206
3207 return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
3208 }
3209
3215 public function hasDelay()
3216 {
3217 global $conf;
3218
3219 //Only valid members
3220 if ($this->status != self::STATUS_VALIDATED) {
3221 return false;
3222 }
3223 if (!$this->datefin) {
3224 return false;
3225 }
3226
3227 $now = dol_now();
3228
3229 return $this->datefin < ($now - getWarningDelay('member', 'subscription'));
3230 }
3231
3232
3241 public function sendReminderForExpiredSubscription($daysbeforeendlist = '10', $fk_adherent_type = 0)
3242 {
3243 global $conf, $langs, $mysoc, $user;
3244
3245 $error = 0;
3246 $this->output = '';
3247 $this->error = '';
3248
3249 $blockingerrormsg = '';
3250
3251 if (!isModEnabled('member')) { // Should not happen. If module disabled, cron job should not be visible.
3252 $langs->load("agenda");
3253 $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3254 return 0;
3255 }
3256 if (!getDolGlobalString('MEMBER_REMINDER_EMAIL')) {
3257 $langs->load("agenda");
3258 $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3259 return 0;
3260 }
3261
3262 $now = dol_now();
3263 $nbok = 0;
3264 $nbko = 0;
3265
3266 $listofmembersok = array();
3267 $listofmembersko = array();
3268
3269 $arraydaysbeforeend = explode(';', $daysbeforeendlist);
3270 foreach ($arraydaysbeforeend as $daysbeforeend) { // Loop on each delay
3271 dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
3272
3273 if (!is_numeric($daysbeforeend)) {
3274 $blockingerrormsg = "Value for delta is not a numeric value";
3275 $nbko++;
3276 break;
3277 }
3278
3279 $tmp = dol_getdate($now);
3280 $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
3281 $datetosearchforend = dol_time_plus_duree(dol_mktime(23, 59, 59, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
3282
3283 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
3284 $sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
3285 $sql .= " AND statut = 1";
3286 $sql .= " AND datefin >= '".$this->db->idate($datetosearchfor)."'";
3287 $sql .= " AND datefin <= '".$this->db->idate($datetosearchforend)."'";
3288 if ((int) $fk_adherent_type > 0) {
3289 $sql .= " AND fk_adherent_type = ".((int) $fk_adherent_type);
3290 }
3291 //$sql .= " LIMIT 10000";
3292
3293 $resql = $this->db->query($sql);
3294 if ($resql) {
3295 $num_rows = $this->db->num_rows($resql);
3296
3297 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
3298 $adherent = new Adherent($this->db);
3299 $formmail = new FormMail($this->db);
3300
3301 $i = 0;
3302 while ($i < $num_rows) {
3303 $obj = $this->db->fetch_object($resql);
3304
3305 $adherent->fetch($obj->rowid, '', 0, '', true, true);
3306
3307 if (empty($adherent->email)) {
3308 $nbko++;
3309 $listofmembersko[$adherent->id] = $adherent->id;
3310 } else {
3311 $thirdpartyres = $adherent->fetch_thirdparty();
3312 if ($thirdpartyres === -1) {
3313 $languagecodeformember = $mysoc->default_lang;
3314 } else {
3315 // 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.
3316 $languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : $adherent->thirdparty->country_code);
3317 $languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
3318 }
3319
3320 // Send reminder email
3321 $outputlangs = new Translate('', $conf);
3322 $outputlangs->setDefaultLang($languagecodeformember);
3323 $outputlangs->loadLangs(array("main", "members"));
3324 dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
3325
3326 $arraydefaultmessage = null;
3327 $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
3328
3329 if (!empty($labeltouse)) {
3330 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
3331 }
3332
3333 if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
3334 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
3335 //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
3336 complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
3337
3338 $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
3339 $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
3340 $email_from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
3341 $to = $adherent->email;
3342 $cc = getDolGlobalString('ADHERENT_CC_MAIL_FROM');
3343
3344 $trackid = 'mem'.$adherent->id;
3345 $moreinheader = 'X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
3346
3347 include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
3348 $cmail = new CMailFile($subject, $to, $email_from, $msg, array(), array(), array(), $cc, '', 0, 1, '', '', $trackid, $moreinheader);
3349 $result = $cmail->sendfile();
3350 if (!$result) {
3351 $error++;
3352 $this->error .= $cmail->error.' ';
3353 if (!is_null($cmail->errors)) {
3354 $this->errors += $cmail->errors;
3355 }
3356 $nbko++;
3357 $listofmembersko[$adherent->id] = $adherent->id;
3358 } else {
3359 $nbok++;
3360 $listofmembersok[$adherent->id] = $adherent->id;
3361
3362 $message = $msg;
3363 $sendto = $to;
3364 $sendtocc = '';
3365 $sendtobcc = '';
3366 $actioncode = 'EMAIL';
3367 $extraparams = array();
3368
3369 $actionmsg = '';
3370 $actionmsg2 = $langs->transnoentities('MailSentByTo', CMailFile::getValidAddress($email_from, 4, 0, 1), CMailFile::getValidAddress($sendto, 4, 0, 1));
3371 if ($message) {
3372 $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($email_from);
3373 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
3374 // if ($sendtocc) {
3375 // $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".dol_escape_htmltag($sendtocc));
3376 // }
3377 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject);
3378 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":");
3379 $actionmsg = dol_concatdesc($actionmsg, $message);
3380 }
3381
3382 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
3383
3384 // Insert record of emails sent
3385 $actioncomm = new ActionComm($this->db);
3386
3387 $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
3388 $actioncomm->code = 'AC_'.$actioncode;
3389 $actioncomm->label = $actionmsg2;
3390 $actioncomm->note_private = $actionmsg;
3391 $actioncomm->fk_project = 0;
3392 $actioncomm->datep = $now;
3393 $actioncomm->datef = $now;
3394 $actioncomm->percentage = -1; // Not applicable
3395 $actioncomm->socid = $adherent->thirdparty->id;
3396 $actioncomm->contact_id = 0;
3397 $actioncomm->authorid = $user->id; // User saving action
3398 $actioncomm->userownerid = $user->id; // Owner of action
3399 // Fields when action is an email (content should be added into note)
3400 $actioncomm->email_msgid = $cmail->msgid;
3401 $actioncomm->email_from = $email_from;
3402 $actioncomm->email_sender = '';
3403 $actioncomm->email_to = $to;
3404 $actioncomm->email_tocc = $sendtocc;
3405 $actioncomm->email_tobcc = $sendtobcc;
3406 $actioncomm->email_subject = $subject;
3407 $actioncomm->errors_to = '';
3408
3409 $actioncomm->fk_element = $adherent->id;
3410 $actioncomm->elementid = $adherent->id;
3411 $actioncomm->elementtype = $adherent->element;
3412
3413 $actioncomm->extraparams = $extraparams;
3414
3415 $actioncomm->create($user);
3416 }
3417 } else {
3418 //$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
3419
3420 $error++;
3421 $this->error .= "Can't find email template with label=".$labeltouse.", to use for the reminding email ";
3422
3423 $nbko++;
3424 $listofmembersko[$adherent->id] = $adherent->id;
3425
3426 break;
3427 }
3428 }
3429
3430 $i++;
3431 }
3432 } else {
3433 $this->error = $this->db->lasterror();
3434 return 1;
3435 }
3436 }
3437
3438 if ($blockingerrormsg) {
3439 $this->error = $blockingerrormsg;
3440 return 1;
3441 } else {
3442 $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
3443 $this->output .= ' Send email successfully to '.$nbok.' members';
3444 $listofids = '';
3445 $i = 0;
3446 foreach ($listofmembersok as $idmember) {
3447 if ($i > 100) {
3448 $listofids .= ', ...';
3449 break;
3450 }
3451 if (empty($listofids)) {
3452 $listofids .= ' [';
3453 } else {
3454 $listofids .= ', ';
3455 }
3456 $listofids .= $idmember;
3457 $i++;
3458 }
3459 if ($listofids) {
3460 $listofids .= ']';
3461 }
3462 $this->output .= ($listofids ? ' ids='.$listofids : '');
3463
3464 if ($nbko) {
3465 $this->output .= ' - Canceled for '.$nbko.' member (no email or email sending error)';
3466 $listofids = '';
3467 $i = 0;
3468 foreach ($listofmembersko as $idmember) {
3469 if ($i > 100) {
3470 $listofids .= ', ...';
3471 break;
3472 }
3473 if (empty($listofids)) {
3474 $listofids .= ' [';
3475 } else {
3476 $listofids .= ', ';
3477 }
3478 $listofids .= $idmember;
3479 $i++;
3480 }
3481 if ($listofids) {
3482 $listofids .= ']';
3483 }
3484 $this->output .= ($listofids ? ' ids='.$listofids : '');
3485 }
3486 }
3487
3488 return $nbko;
3489 }
3490
3498 public function getKanbanView($option = '', $arraydata = null)
3499 {
3500 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
3501
3502 $return = '<div class="box-flex-item box-flex-grow-zero">';
3503 $return .= '<div class="info-box info-box-sm">';
3504 $return .= '<span class="info-box-icon bg-infobox-action">';
3505 if (!empty($this->photo)) {
3506 $return .= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photowithmargin photologintooltip', 'small', 0, 1);
3507 } else {
3508 $return .= img_picto('', 'user');
3509 }
3510 $return .= '</span>';
3511 $return .= '<div class="info-box-content">';
3512 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl() . '</span>';
3513 if ($selected >= 0) {
3514 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
3515 }
3516 $return .= '<br><span class="info-box-label paddingright">'.$this->getmorphylib('', 2).'</span>';
3517 $return .= '<span class="info-box-label opacitymedium">'.$this->type.'</span>';
3518
3519 $return .= '<br><div class="info-box-status paddingtop">';
3520 $return .= $this->LibStatut($this->status, $this->need_subscription, $this->datefin, 5);
3521 $return .= '</div>';
3522 $return .= '</div>';
3523 $return .= '</div>';
3524 $return .= '</div>';
3525 return $return;
3526 }
3527}
$object ref
Definition info.php:90
Class to manage bank accounts.
Class to manage agenda events (actions)
Class to manage members of a foundation.
mergeMembers($member_origin_id)
Merge a member with current one, deleting the given company $member_origin_id.
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)
Returns the complete DN (Distinguished Name) string in the LDAP directory for the object.
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.
del_to_abo()
Function to delete a member from external tools like mailing-list, spip, etc.
resiliate($user)
Function that terminates a member.
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.
subscription($date, $amount, $accountid=0, $operation='', $label='', $num_chq='', $emetteur_nom='', $emetteur_banque='', $datesubend=0, $fk_type=null, $ref_ext='')
Insert subscription into database and eventually add links to banks, mailman, etc....
__construct($db)
Constructor.
validate($user, $notrigger=0)
Function that validate a member.
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,...
fetch($rowid, $ref='', $socid=0, $ref_ext='', $fetch_optionals=true, $fetch_subscriptions=true)
Load member from database.
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.
Class to manage categories.
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.
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, $usesharelinkifavailable=0)
Return HTML code to output a photo.
Class to manage a HTML form to send a unitary email Usage: $formail = new FormMail($db) $formmail->pr...
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:169
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.
global $mysoc
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
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").
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_move($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array(), $entity=null)
Move a file into another name.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:64
dol_is_dir($folder)
Test if filename is a directory.
clean_url($url, $http=1)
Clean an url string.
dol_now($mode='gmt')
Return date for now.
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 '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
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.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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.
isModEnabled($module)
Is Dolibarr module enabled.
getWarningDelay($module, $parmlevel1, $parmlevel2='')
Return a warning delay You can use it like this: if (getWarningDelay('module', 'paramlevel1')) It rep...
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
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
getRandomPassword($generic=false, $replaceambiguouschars=null, $length=32)
Return a generated password using default module.
dolGetLdapPasswordHash($password, $type='md5')
Returns a specific ldap hash of a password.
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.