Passed
Push — EXTRACT_CLASSES ( a2ff75...ae6b5c )
by Rafael
34:15
created

Adherent   F

Complexity

Total Complexity 507

Size/Duplication

Total Lines 3245
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 1739
dl 0
loc 3245
rs 0.8
c 0
b 0
f 0
wmc 507

How to fix   Complexity   

Complex Class

Complex classes like Adherent often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Adherent, and based on these observations, apply Extract Interface, too.

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