Adherent::update_end_date()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 40
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 31
nc 5
nop 1
dl 0
loc 40
rs 9.424
c 0
b 0
f 0
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\Code\Categories\Classes\Categorie;
45
use Dolibarr\Code\Compta\Classes\Facture;
46
use Dolibarr\Code\Core\Classes\CMailFile;
47
use Dolibarr\Code\Core\Classes\Form;
48
use Dolibarr\Code\Core\Classes\WorkboardResponse;
49
use Dolibarr\Code\Core\Traits\CommonPeople;
50
use Dolibarr\Code\Societe\Classes\Societe;
51
use Dolibarr\Code\User\Classes\User;
52
use Dolibarr\Core\Base\CommonObject;
53
use DoliDB;
54
use Exception;
55
56
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php';
57
58
/**
59
 *      Class to manage members of a foundation
60
 */
61
class Adherent extends CommonObject
62
{
63
    use CommonPeople;
0 ignored issues
show
introduced by
The trait Dolibarr\Code\Core\Traits\CommonPeople requires some properties which are not provided by Dolibarr\Code\Adherents\Classes\Adherent: $MAIN_SHOW_REGION_IN_STATE_SELECT, $attributes, $global, $nom, $use_javascript_ajax, $office_fax
Loading history...
64
65
    /**
66
     * @var string ID to identify managed object
67
     */
68
    public $element = 'member';
69
70
    /**
71
     * @var string Name of table without prefix where object is stored
72
     */
73
    public $table_element = 'adherent';
74
75
    /**
76
     * @var string picto
77
     */
78
    public $picto = 'member';
79
80
    /**
81
     * @var string[] array of messages
82
     */
83
    public $mesgs;
84
85
    /**
86
     * @var string login of member
87
     */
88
    public $login;
89
90
    /**
91
     * @var string Clear password in memory
92
     */
93
    public $pass;
94
95
    /**
96
     * @var string Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
97
     */
98
    public $pass_indatabase;
99
100
    /**
101
     * @var string Encrypted password in database (always defined)
102
     */
103
    public $pass_indatabase_crypted;
104
105
    /**
106
     * @var string fullname
107
     */
108
    public $fullname;
109
110
    /**
111
     * @var string
112
     * @deprecated
113
     * @see $civility_code
114
     */
115
    public $civility_id;
116
117
    /**
118
     * @var string The civility code, not an integer (ex: 'MR', 'MME', 'MLE', etc.)
119
     */
120
    public $civility_code;
121
122
    public $civility;
123
124
    /**
125
     * @var string company name
126
     * @deprecated
127
     * @see $company
128
     */
129
    public $societe;
130
131
    /**
132
     * @var string company name
133
     */
134
    public $company;
135
136
    /**
137
     * @var int Thirdparty ID
138
     * @deprecated
139
     * @see $socid
140
     */
141
    public $fk_soc;
142
143
    /**
144
     * @var int socid
145
     */
146
    public $socid;
147
148
    /**
149
     * @var array array of socialnetworks
150
     */
151
    public $socialnetworks;
152
153
    /**
154
     * @var string Phone number
155
     */
156
    public $phone;
157
158
    /**
159
     * @var string Private Phone number
160
     */
161
    public $phone_perso;
162
163
    /**
164
     * @var string Professional Phone number
165
     */
166
    public $phone_pro;
167
168
    /**
169
     * @var string Mobile phone number
170
     */
171
    public $phone_mobile;
172
173
    /**
174
     * @var string Fax number
175
     */
176
    public $fax;
177
178
    /**
179
     * @var string Function
180
     */
181
    public $poste;
182
183
    /**
184
     * @var string mor or phy
185
     */
186
    public $morphy;
187
188
    /**
189
     * @var int Info can be public
190
     */
191
    public $public;
192
193
    /**
194
     * Default language code of member (en_US, ...)
195
     * @var string
196
     */
197
    public $default_lang;
198
199
    /**
200
     * @var string photo of member
201
     */
202
    public $photo;
203
204
    /**
205
     * Date creation record (datec)
206
     *
207
     * @var integer
208
     */
209
    public $datec;
210
211
    /**
212
     * Date modification record (tms)
213
     *
214
     * @var integer
215
     */
216
    public $datem;
217
218
    public $datevalid;
219
220
    /**
221
     * @var string gender
222
     */
223
    public $gender;
224
225
    /**
226
     * @var int|string date of birth
227
     */
228
    public $birth;
229
230
    /**
231
     * @var int id type member
232
     */
233
    public $typeid;
234
235
    /**
236
     * @var string label type member
237
     */
238
    public $type;
239
240
    /**
241
     * @var int need_subscription
242
     */
243
    public $need_subscription;
244
245
    /**
246
     * @var int user_id
247
     */
248
    public $user_id;
249
250
    /**
251
     * @var string user_login
252
     */
253
    public $user_login;
254
255
    public $datefin;
256
257
258
    // Fields loaded by fetch_subscriptions() from member table
259
260
    /**
261
     * @var int|string date
262
     */
263
    public $first_subscription_date;
264
265
    /**
266
     * @var int|string date
267
     */
268
    public $first_subscription_date_start;
269
270
    /**
271
     * @var int|string date
272
     */
273
    public $first_subscription_date_end;
274
275
    /**
276
     * @var int|string date
277
     */
278
    public $first_subscription_amount;
279
280
    /**
281
     * @var int|string date
282
     */
283
    public $last_subscription_date;
284
285
    /**
286
     * @var int|string date
287
     */
288
    public $last_subscription_date_start;
289
290
    /**
291
     * @var int|string date
292
     */
293
    public $last_subscription_date_end;
294
295
    /**
296
     * @var int|string date
297
     */
298
    public $last_subscription_amount;
299
300
    /**
301
     * @var array
302
     */
303
    public $subscriptions = array();
304
305
    /**
306
     * @var string ip
307
     */
308
    public $ip;
309
310
    // Fields loaded by fetchPartnerships() from partnership table
311
312
    public $partnerships = array();
313
314
    /**
315
     * @var Facture|null        To store the created invoice into subscriptionComplementaryActions()
316
     */
317
    public $invoice;
318
319
320
    /**
321
     * @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.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,array{type:...ring>,comment?:string}> at position 16 could not be parsed: Expected '}' at position 16, but found 'int'.
Loading history...
322
     */
323
    public $fields = array(
324
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
325
        'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
326
        'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 15, 'index' => 1),
327
        'ref_ext' => array('type' => 'varchar(128)', 'label' => 'Ref ext', 'enabled' => 1, 'visible' => 0, 'position' => 20),
328
        'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
329
        'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
330
        'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
331
        'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => 1, 'position' => 40),
332
        'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => -1, 'position' => 45),
333
        'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => -1, 'position' => 50),
334
        'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
335
        'fk_adherent_type' => array('type' => 'integer', 'label' => 'Fk adherent type', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
336
        'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
337
        'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
338
        'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
339
        'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
340
        'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
341
        'state_id' => array('type' => 'integer', 'label' => 'State id', 'enabled' => 1, 'visible' => -1, 'position' => 90),
342
        'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
343
        'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
344
        'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
345
        'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
346
        'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
347
        'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
348
        'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => -1, 'position' => 128),
349
        'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
350
        'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
351
        'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
352
        'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 145),
353
        'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
354
        'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
355
        'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
356
        'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
357
        'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
358
        'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
359
        'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
360
        'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 180),
361
        'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user mod', 'enabled' => 1, 'visible' => -1, 'position' => 185),
362
        'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 190),
363
        'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => -1, 'position' => 195),
364
        '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')),
365
        'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
366
        'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805)
367
    );
368
369
    /**
370
     * Draft status
371
     */
372
    const STATUS_DRAFT = -1;
373
    /**
374
     * Validated status
375
     */
376
    const STATUS_VALIDATED = 1;
377
    /**
378
     * Resiliated
379
     */
380
    const STATUS_RESILIATED = 0;
381
    /**
382
     * Excluded
383
     */
384
    const STATUS_EXCLUDED = -2;
385
386
387
    /**
388
     *  Constructor
389
     *
390
     *  @param      DoliDB      $db     Database handler
391
     */
392
    public function __construct($db)
393
    {
394
        $this->db = $db;
395
        $this->statut = self::STATUS_DRAFT;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

395
        /** @scrutinizer ignore-deprecated */ $this->statut = self::STATUS_DRAFT;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
396
        $this->status = self::STATUS_DRAFT;
397
        // l'adherent n'est pas public par default
398
        $this->public = 0;
399
        $this->ismultientitymanaged = 1;
400
        $this->isextrafieldmanaged = 1;
401
        // les champs optionnels sont vides
402
        $this->array_options = array();
403
    }
404
405
406
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
407
    /**
408
     *  Function sending an email to the current member with the text supplied in parameter.
409
     *
410
     *  @param  string  $text               Content of message (not html entities encoded)
411
     *  @param  string  $subject            Subject of message
412
     *  @param  array   $filename_list      Array of attached files
413
     *  @param  array   $mimetype_list      Array of mime types of attached files
414
     *  @param  array   $mimefilename_list  Array of public names of attached files
415
     *  @param  string  $addr_cc            Email cc
416
     *  @param  string  $addr_bcc           Email bcc
417
     *  @param  int     $deliveryreceipt    Ask a delivery receipt
418
     *  @param  int     $msgishtml          1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
419
     *  @param  string  $errors_to          errors to
420
     *  @param  string  $moreinheader       Add more html headers
421
     *  @deprecated since V18
422
     *  @see sendEmail()
423
     *  @return int                         Return integer <0 if KO, >0 if OK
424
     */
425
    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 = '')
426
    {
427
		// phpcs:enable
428
        dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
429
430
        return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
431
    }
432
433
    /**
434
     *  Function sending an email to the current member with the text supplied in parameter.
435
     *
436
     *  @param  string  $text               Content of message (not html entities encoded)
437
     *  @param  string  $subject            Subject of message
438
     *  @param  array   $filename_list      Array of attached files
439
     *  @param  array   $mimetype_list      Array of mime types of attached files
440
     *  @param  array   $mimefilename_list  Array of public names of attached files
441
     *  @param  string  $addr_cc            Email cc
442
     *  @param  string  $addr_bcc           Email bcc
443
     *  @param  int     $deliveryreceipt    Ask a delivery receipt
444
     *  @param  int     $msgishtml          1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
445
     *  @param  string  $errors_to          errors to
446
     *  @param  string  $moreinheader       Add more html headers
447
     *  @since V18
448
     *  @return int                         Return integer <0 if KO, >0 if OK
449
     */
450
    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 = '')
451
    {
452
        global $conf, $langs;
453
454
        // Detect if message is HTML
455
        if ($msgishtml == -1) {
456
            $msgishtml = 0;
457
            if (dol_textishtml($text, 0)) {
458
                $msgishtml = 1;
459
            }
460
        }
461
462
        dol_syslog('sendEmail msgishtml=' . $msgishtml);
463
464
        $texttosend = $this->makeSubstitution($text);
465
        $subjecttosend = $this->makeSubstitution($subject);
466
        if ($msgishtml) {
467
            $texttosend = dol_htmlentitiesbr($texttosend);
468
        }
469
470
        // Envoi mail confirmation
471
        $from = $conf->email_from;
472
        if (getDolGlobalString('ADHERENT_MAIL_FROM')) {
473
            $from = getDolGlobalString('ADHERENT_MAIL_FROM');
474
        }
475
476
        $trackid = 'mem' . $this->id;
477
478
        // Send email (substitutionarray must be done just before this)
479
        $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
480
        if ($mailfile->sendfile()) {
481
            return 1;
482
        } else {
483
            $this->error = $langs->trans("ErrorFailedToSendMail", $from, $this->email) . '. ' . $mailfile->error;
484
            return -1;
485
        }
486
    }
487
488
489
    /**
490
     * Make substitution of tags into text with value of current object.
491
     *
492
     * @param   string  $text       Text to make substitution to
493
     * @return  string              Value of input text string with substitutions done
494
     */
495
    public function makeSubstitution($text)
496
    {
497
        global $langs;
498
499
        $birthday = dol_print_date($this->birth, 'day');
500
501
        $msgishtml = 0;
502
        if (dol_textishtml($text, 1)) {
503
            $msgishtml = 1;
504
        }
505
506
        $infos = '';
507
        if ($this->civility_id) {
508
            $infos .= $langs->transnoentities("UserTitle") . ": " . $this->getCivilityLabel() . "\n";
509
        }
510
        $infos .= $langs->transnoentities("id") . ": " . $this->id . "\n";
511
        $infos .= $langs->transnoentities("ref") . ": " . $this->ref . "\n";
512
        $infos .= $langs->transnoentities("Lastname") . ": " . $this->lastname . "\n";
513
        $infos .= $langs->transnoentities("Firstname") . ": " . $this->firstname . "\n";
514
        $infos .= $langs->transnoentities("Company") . ": " . $this->company . "\n";
515
        $infos .= $langs->transnoentities("Address") . ": " . $this->address . "\n";
516
        $infos .= $langs->transnoentities("Zip") . ": " . $this->zip . "\n";
517
        $infos .= $langs->transnoentities("Town") . ": " . $this->town . "\n";
518
        $infos .= $langs->transnoentities("Country") . ": " . $this->country . "\n";
519
        $infos .= $langs->transnoentities("EMail") . ": " . $this->email . "\n";
520
        $infos .= $langs->transnoentities("PhonePro") . ": " . $this->phone . "\n";
521
        $infos .= $langs->transnoentities("PhonePerso") . ": " . $this->phone_perso . "\n";
522
        $infos .= $langs->transnoentities("PhoneMobile") . ": " . $this->phone_mobile . "\n";
523
        if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
524
            $infos .= $langs->transnoentities("Login") . ": " . $this->login . "\n";
525
            $infos .= $langs->transnoentities("Password") . ": " . $this->pass . "\n";
526
        }
527
        $infos .= $langs->transnoentities("Birthday") . ": " . $birthday . "\n";
528
        $infos .= $langs->transnoentities("Photo") . ": " . $this->photo . "\n";
529
        $infos .= $langs->transnoentities("Public") . ": " . yn($this->public);
530
531
        // Substitutions
532
        $substitutionarray = array(
533
            '__ID__' => $this->id,
534
            '__REF__' => $this->ref,
535
            '__MEMBER_ID__' => $this->id,
536
            '__CIVILITY__' => $this->getCivilityLabel(),
537
            '__FIRSTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->firstname) : ($this->firstname ? $this->firstname : ''),
538
            '__LASTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->lastname) : ($this->lastname ? $this->lastname : ''),
539
            '__FULLNAME__' => $msgishtml ? dol_htmlentitiesbr($this->getFullName($langs)) : $this->getFullName($langs),
540
            '__COMPANY__' => $msgishtml ? dol_htmlentitiesbr($this->company) : ($this->company ? $this->company : ''),
541
            '__ADDRESS__' => $msgishtml ? dol_htmlentitiesbr($this->address) : ($this->address ? $this->address : ''),
542
            '__ZIP__' => $msgishtml ? dol_htmlentitiesbr($this->zip) : ($this->zip ? $this->zip : ''),
543
            '__TOWN__' => $msgishtml ? dol_htmlentitiesbr($this->town) : ($this->town ? $this->town : ''),
544
            '__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''),
545
            '__EMAIL__' => $msgishtml ? dol_htmlentitiesbr($this->email) : ($this->email ? $this->email : ''),
546
            '__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''),
547
            '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($this->photo) : ($this->photo ? $this->photo : ''),
548
            '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($this->login) : ($this->login ? $this->login : ''),
549
            '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($this->pass) : ($this->pass ? $this->pass : ''),
550
            '__PHONE__' => $msgishtml ? dol_htmlentitiesbr($this->phone) : ($this->phone ? $this->phone : ''),
551
            '__PHONEPRO__' => $msgishtml ? dol_htmlentitiesbr($this->phone_perso) : ($this->phone_perso ? $this->phone_perso : ''),
552
            '__PHONEMOBILE__' => $msgishtml ? dol_htmlentitiesbr($this->phone_mobile) : ($this->phone_mobile ? $this->phone_mobile : ''),
553
            '__TYPE__' => $msgishtml ? dol_htmlentitiesbr($this->type) : ($this->type ? $this->type : '')
554
        );
555
556
        complete_substitutions_array($substitutionarray, $langs, $this);
557
558
        return make_substitutions($text, $substitutionarray, $langs);
559
    }
560
561
562
    /**
563
     *  Return translated label by the nature of a adherent (physical or moral)
564
     *
565
     *  @param  string      $morphy     Nature of the adherent (physical or moral)
566
     *  @param  int<0,2>    $addbadge   Add badge (1=Full label, 2=First letters only)
567
     *  @return string                  Label
568
     */
569
    public function getmorphylib($morphy = '', $addbadge = 0)
570
    {
571
        global $langs;
572
        $s = '';
573
574
        // Clean var
575
        if (!$morphy) {
576
            $morphy = $this->morphy;
577
        }
578
579
        if ($addbadge) {
580
            $labeltoshowm = $langs->trans("Moral");
581
            $labeltoshowp = $langs->trans("Physical");
582
            if ($morphy == 'phy') {
583
                $labeltoshow = $labeltoshowp;
584
                if ($addbadge == 2) {
585
                    $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp));
586
                    if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowm))) {
587
                        $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp, 2));
588
                    }
589
                }
590
                $s .= '<span class="member-individual-back paddingleftimp paddingrightimp" title="' . $langs->trans("Physical") . '">' . $labeltoshow . '</span>';
591
            }
592
            if ($morphy == 'mor') {
593
                $labeltoshow = $labeltoshowm;
594
                if ($addbadge == 2) {
595
                    $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm));
596
                    if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowp))) {
597
                        $labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm, 2));
598
                    }
599
                }
600
                $s .= '<span class="member-company-back paddingleftimp paddingrightimp" title="' . $langs->trans("Moral") . '">' . $labeltoshow . '</span>';
601
            }
602
        } else {
603
            if ($morphy == 'phy') {
604
                $s = $langs->trans("Physical");
605
            } elseif ($morphy == 'mor') {
606
                $s = $langs->trans("Moral");
607
            }
608
        }
609
610
        return $s;
611
    }
612
613
    /**
614
     *  Create a member into database
615
     *
616
     *  @param  User    $user           Object user qui demande la creation
617
     *  @param  int     $notrigger      1 ne declenche pas les triggers, 0 sinon
618
     *  @return int                     Return integer <0 if KO, >0 if OK
619
     */
620
    public function create($user, $notrigger = 0)
621
    {
622
        global $conf, $langs, $mysoc;
623
624
        $error = 0;
625
626
        $now = dol_now();
627
628
        // Clean parameters
629
        $this->import_key = trim($this->import_key);
630
631
        // Check parameters
632
        if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
633
            $langs->load("errors");
634
            $this->error = $langs->trans("ErrorBadEMail", $this->email);
635
            return -1;
636
        }
637
        if (!$this->datec) {
638
            $this->datec = $now;
639
        }
640
        if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
641
            if (empty($this->login)) {
642
                $this->error = $langs->trans("ErrorWrongValueForParameterX", "Login");
643
                return -1;
644
            }
645
        }
646
647
        $this->db->begin();
648
649
        // Insert member
650
        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "adherent";
651
        $sql .= " (ref, datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key, ip)";
652
        $sql .= " VALUES (";
653
        $sql .= " '(PROV)'";
654
        $sql .= ", '" . $this->db->idate($this->datec) . "'";
655
        $sql .= ", " . ($this->login ? "'" . $this->db->escape($this->login) . "'" : "null");
656
        $sql .= ", " . ($user->id > 0 ? $user->id : "null"); // Can be null because member can be created by a guest or a script
657
        $sql .= ", null, null, '" . $this->db->escape($this->morphy) . "'";
658
        $sql .= ", " . ((int) $this->typeid);
659
        $sql .= ", " . $conf->entity;
660
        $sql .= ", " . (!empty($this->import_key) ? "'" . $this->db->escape($this->import_key) . "'" : "null");
661
        $sql .= ", " . (!empty($this->ip) ? "'" . $this->db->escape($this->ip) . "'" : "null");
662
        $sql .= ")";
663
664
        dol_syslog(get_only_class($this) . "::create", LOG_DEBUG);
665
        $result = $this->db->query($sql);
666
        if ($result) {
667
            $id = $this->db->last_insert_id(MAIN_DB_PREFIX . "adherent");
668
            if ($id > 0) {
669
                $this->id = $id;
670
                if (getDolGlobalString('MEMBER_CODEMEMBER_ADDON') == '') {
671
                    // keep old numbering
672
                    $this->ref = (string) $id;
673
                } else {
674
                    // auto code
675
                    $modfile = dol_buildpath('core/modules/member/' . getDolGlobalString('MEMBER_CODEMEMBER_ADDON') . '.php', 0);
676
                    try {
677
                        require_once $modfile;
678
                        $modname = getDolGlobalString('MEMBER_CODEMEMBER_ADDON');
679
                        $modCodeMember = new $modname();
680
                        '@phan-var-force ModeleNumRefMembers $modCodeMember';
681
                        $this->ref = $modCodeMember->getNextValue($mysoc, $this);
682
                    } catch (Exception $e) {
683
                        dol_syslog($e->getMessage(), LOG_ERR);
684
                        $error++;
685
                    }
686
                }
687
688
                // Update minor fields
689
                $result = $this->update($user, 1, 1, 0, 0, 'add'); // nosync is 1 to avoid update data of user
690
                if ($result < 0) {
691
                    $this->db->rollback();
692
                    return -1;
693
                }
694
695
                // Add link to user
696
                if ($this->user_id) {
697
                    // Add link to user
698
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "user SET";
699
                    $sql .= " fk_member = " . ((int) $this->id);
700
                    $sql .= " WHERE rowid = " . ((int) $this->user_id);
701
                    dol_syslog(get_only_class($this) . "::create", LOG_DEBUG);
702
                    $resql = $this->db->query($sql);
703
                    if (!$resql) {
704
                        $this->error = 'Failed to update user to make link with member';
705
                        $this->db->rollback();
706
                        return -4;
707
                    }
708
                }
709
710
                if (!$notrigger) {
711
                    // Call trigger
712
                    $result = $this->call_trigger('MEMBER_CREATE', $user);
713
                    if ($result < 0) {
714
                        $error++;
715
                    }
716
                    // End call triggers
717
                }
718
719
                if (count($this->errors)) {
720
                    dol_syslog(get_only_class($this) . "::create " . implode(',', $this->errors), LOG_ERR);
721
                    $this->db->rollback();
722
                    return -3;
723
                } else {
724
                    $this->db->commit();
725
                    return $this->id;
726
                }
727
            } else {
728
                $this->error = 'Failed to get last insert id';
729
                dol_syslog(get_only_class($this) . "::create " . $this->error, LOG_ERR);
730
                $this->db->rollback();
731
                return -2;
732
            }
733
        } else {
734
            $this->error = $this->db->error();
735
            $this->db->rollback();
736
            return -1;
737
        }
738
    }
739
740
741
    /**
742
     *  Update a member in database (standard information and password)
743
     *
744
     *  @param  User    $user               User making update
745
     *  @param  int     $notrigger          1=disable trigger UPDATE (when called by create)
746
     *  @param  int     $nosyncuser         0=Synchronize linked user (standard info), 1=Do not synchronize linked user
747
     *  @param  int     $nosyncuserpass     0=Synchronize linked user (password), 1=Do not synchronize linked user
748
     *  @param  int     $nosyncthirdparty   0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty
749
     *  @param  string  $action             Current action for hookmanager
750
     *  @return int                         Return integer <0 if KO, >0 if OK
751
     */
752
    public function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
753
    {
754
        global $langs, $hookmanager;
755
756
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/functions2.lib.php';
757
758
        $nbrowsaffected = 0;
759
        $error = 0;
760
761
        dol_syslog(get_only_class($this) . "::update notrigger=" . $notrigger . ", nosyncuser=" . $nosyncuser . ", nosyncuserpass=" . $nosyncuserpass . " nosyncthirdparty=" . $nosyncthirdparty . ", email=" . $this->email);
762
763
        // Clean parameters
764
        $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
765
        $this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
766
        $this->gender = trim($this->gender);
767
        // $this->address = ($this->address ? $this->address : $this->address);
768
        // $this->zip = ($this->zip ? $this->zip : $this->zip);
769
        // $this->town = ($this->town ? $this->town : $this->town);
770
        // $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
771
        // $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id);
772
        // $this->note_public = ($this->note_public ? $this->note_public : $this->note_public);
773
        // $this->note_private = ($this->note_private ? $this->note_private : $this->note_private);
774
        $this->url = $this->url ? clean_url($this->url, 0) : '';
775
        $this->setUpperOrLowerCase();
776
        // Check parameters
777
        if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail($this->email)) {
778
            $langs->load("errors");
779
            $this->error = $langs->trans("ErrorBadEMail", $this->email);
780
            return -1;
781
        }
782
783
        $this->db->begin();
784
785
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
786
        $sql .= " ref = '" . $this->db->escape($this->ref) . "'";
787
        $sql .= ", civility = " . ($this->civility_id ? "'" . $this->db->escape($this->civility_id) . "'" : "null");
788
        $sql .= ", firstname = " . ($this->firstname ? "'" . $this->db->escape($this->firstname) . "'" : "null");
789
        $sql .= ", lastname = " . ($this->lastname ? "'" . $this->db->escape($this->lastname) . "'" : "null");
790
        $sql .= ", gender = " . ($this->gender != -1 ? "'" . $this->db->escape($this->gender) . "'" : "null"); // 'man' or 'woman'
791
        $sql .= ", login = " . ($this->login ? "'" . $this->db->escape($this->login) . "'" : "null");
792
        $sql .= ", societe = " . ($this->company ? "'" . $this->db->escape($this->company) . "'" : ($this->societe ? "'" . $this->db->escape($this->societe) . "'" : "null"));
793
        if ($this->socid) {
794
            $sql .= ", fk_soc = " . ($this->socid > 0 ? (int) $this->socid : "null");  // Must be modified only when creating from a third-party
795
        }
796
        $sql .= ", address = " . ($this->address ? "'" . $this->db->escape($this->address) . "'" : "null");
797
        $sql .= ", zip = " . ($this->zip ? "'" . $this->db->escape($this->zip) . "'" : "null");
798
        $sql .= ", town = " . ($this->town ? "'" . $this->db->escape($this->town) . "'" : "null");
799
        $sql .= ", country = " . ($this->country_id > 0 ? (int) $this->country_id : "null");
800
        $sql .= ", state_id = " . ($this->state_id > 0 ? (int) $this->state_id : "null");
801
        $sql .= ", email = '" . $this->db->escape($this->email) . "'";
802
        $sql .= ", url = " . (!empty($this->url) ? "'" . $this->db->escape($this->url) . "'" : "null");
803
        $sql .= ", socialnetworks = " . ($this->socialnetworks ? "'" . $this->db->escape(json_encode($this->socialnetworks)) . "'" : "null");
804
        $sql .= ", phone = " . ($this->phone ? "'" . $this->db->escape($this->phone) . "'" : "null");
805
        $sql .= ", phone_perso = " . ($this->phone_perso ? "'" . $this->db->escape($this->phone_perso) . "'" : "null");
806
        $sql .= ", phone_mobile = " . ($this->phone_mobile ? "'" . $this->db->escape($this->phone_mobile) . "'" : "null");
807
        $sql .= ", note_private = " . ($this->note_private ? "'" . $this->db->escape($this->note_private) . "'" : "null");
808
        $sql .= ", note_public = " . ($this->note_public ? "'" . $this->db->escape($this->note_public) . "'" : "null");
809
        $sql .= ", photo = " . ($this->photo ? "'" . $this->db->escape($this->photo) . "'" : "null");
810
        $sql .= ", public = '" . $this->db->escape($this->public) . "'";
811
        $sql .= ", statut = " . (int) $this->statut;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

811
        $sql .= ", statut = " . (int) /** @scrutinizer ignore-deprecated */ $this->statut;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
812
        $sql .= ", default_lang = " . (!empty($this->default_lang) ? "'" . $this->db->escape($this->default_lang) . "'" : "null");
813
        $sql .= ", fk_adherent_type = " . (int) $this->typeid;
814
        $sql .= ", morphy = '" . $this->db->escape($this->morphy) . "'";
815
        $sql .= ", birth = " . ($this->birth ? "'" . $this->db->idate($this->birth) . "'" : "null");
816
817
        if ($this->datefin) {
818
            $sql .= ", datefin = '" . $this->db->idate($this->datefin) . "'"; // Must be modified only when deleting a subscription
819
        }
820
        if ($this->datevalid) {
821
            $sql .= ", datevalid = '" . $this->db->idate($this->datevalid) . "'"; // Must be modified only when validating a member
822
        }
823
        $sql .= ", fk_user_mod = " . ($user->id > 0 ? $user->id : 'null'); // Can be null because member can be create by a guest
824
        $sql .= " WHERE rowid = " . ((int) $this->id);
825
826
        // If we change the type of membership, we set also label of new type
827
        if (!empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid) {
0 ignored issues
show
Bug Best Practice introduced by
The property typeid does not exist on Dolibarr\Core\Base\CommonObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
828
            $sql2 = "SELECT libelle as label";
829
            $sql2 .= " FROM " . MAIN_DB_PREFIX . "adherent_type";
830
            $sql2 .= " WHERE rowid = " . ((int) $this->typeid);
831
            $resql2 = $this->db->query($sql2);
832
            if ($resql2) {
833
                while ($obj = $this->db->fetch_object($resql2)) {
834
                    $this->type = $obj->label;
835
                }
836
            }
837
        }
838
839
        dol_syslog(get_only_class($this) . "::update update member", LOG_DEBUG);
840
        $resql = $this->db->query($sql);
841
        if ($resql) {
842
            unset($this->country_code);
843
            unset($this->country);
844
            unset($this->state_code);
845
            unset($this->state);
846
847
            $nbrowsaffected += $this->db->affected_rows($resql);
848
849
            $action = 'update';
850
851
            // Actions on extra fields
852
            if (!$error) {
853
                $result = $this->insertExtraFields();
854
                if ($result < 0) {
855
                    $error++;
856
                }
857
            }
858
859
            // Update password
860
            if (!$error && $this->pass) {
861
                dol_syslog(get_only_class($this) . "::update update password");
862
                if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) {
863
                    $isencrypted = getDolGlobalString('DATABASE_PWD_ENCRYPTED') ? 1 : 0;
864
865
                    // If password to set differs from the one found into database
866
                    $result = $this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
867
                    if (!$nbrowsaffected) {
868
                        $nbrowsaffected++;
869
                    }
870
                }
871
            }
872
873
            // Remove links to user and replace with new one
874
            if (!$error) {
875
                dol_syslog(get_only_class($this) . "::update update link to user");
876
                $sql = "UPDATE " . MAIN_DB_PREFIX . "user SET fk_member = NULL WHERE fk_member = " . ((int) $this->id);
877
                dol_syslog(get_only_class($this) . "::update", LOG_DEBUG);
878
                $resql = $this->db->query($sql);
879
                if (!$resql) {
880
                    $this->error = $this->db->error();
881
                    $this->db->rollback();
882
                    return -5;
883
                }
884
                // If there is a user linked to this member
885
                if ($this->user_id > 0) {
886
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "user SET fk_member = " . ((int) $this->id) . " WHERE rowid = " . ((int) $this->user_id);
887
                    dol_syslog(get_only_class($this) . "::update", LOG_DEBUG);
888
                    $resql = $this->db->query($sql);
889
                    if (!$resql) {
890
                        $this->error = $this->db->error();
891
                        $this->db->rollback();
892
                        return -5;
893
                    }
894
                }
895
            }
896
897
            if (!$error && $nbrowsaffected) { // If something has change in main data
898
                // Update information on linked user if it is an update
899
                if (!$error && $this->user_id > 0 && !$nosyncuser) {
900
                    dol_syslog(get_only_class($this) . "::update update linked user");
901
902
                    $luser = new User($this->db);
903
                    $result = $luser->fetch($this->user_id);
904
905
                    if ($result >= 0) {
906
                        //var_dump($this->user_login);exit;
907
                        //var_dump($this->login);exit;
908
909
                        // 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.
910
                        if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
911
                            $luser->login = $this->login;
912
                        }
913
914
                        $luser->ref = $this->ref;
915
                        $luser->civility_id = $this->civility_id;
916
                        $luser->firstname = $this->firstname;
917
                        $luser->lastname = $this->lastname;
918
                        $luser->gender = $this->gender;
919
                        $luser->pass = $this->pass;
920
                        //$luser->socid=$this->fk_soc;      // We do not enable this. This may transform a user into an external user.
921
922
                        $luser->birth = $this->birth;
923
924
                        $luser->address = $this->address;
925
                        $luser->zip = $this->zip;
926
                        $luser->town = $this->town;
927
                        $luser->country_id = $this->country_id;
928
                        $luser->state_id = $this->state_id;
929
930
                        $luser->email = $this->email;
931
                        $luser->socialnetworks = $this->socialnetworks;
932
                        $luser->office_phone = $this->phone;
933
                        $luser->user_mobile = $this->phone_mobile;
934
935
                        $luser->lang = $this->default_lang;
936
937
                        $luser->fk_member = $this->id;
938
939
                        $result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
940
                        if ($result < 0) {
941
                            $this->error = $luser->error;
942
                            dol_syslog(get_only_class($this) . "::update " . $this->error, LOG_ERR);
943
                            $error++;
944
                        }
945
                    } else {
946
                        $this->error = $luser->error;
947
                        $error++;
948
                    }
949
                }
950
951
                // Update information on linked thirdparty if it is an update
952
                if (!$error && $this->fk_soc > 0 && !$nosyncthirdparty) {
953
                    dol_syslog(get_only_class($this) . "::update update linked thirdparty");
954
955
                    // This member is linked with a thirdparty, so we also update thirdparty information
956
                    // if this is an update.
957
                    $lthirdparty = new Societe($this->db);
958
                    $result = $lthirdparty->fetch($this->fk_soc);
959
960
                    if ($result > 0) {
961
                        $lthirdparty->address = $this->address;
962
                        $lthirdparty->zip = $this->zip;
963
                        $lthirdparty->town = $this->town;
964
                        $lthirdparty->email = $this->email;
965
                        $lthirdparty->socialnetworks = $this->socialnetworks;
966
                        $lthirdparty->phone = $this->phone;
967
                        $lthirdparty->state_id = $this->state_id;
968
                        $lthirdparty->country_id = $this->country_id;
969
                        //$lthirdparty->phone_mobile=$this->phone_mobile;
970
                        $lthirdparty->default_lang = $this->default_lang;
971
972
                        $result = $lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
973
974
                        if ($result < 0) {
975
                            $this->error = $lthirdparty->error;
976
                            $this->errors = $lthirdparty->errors;
977
                            dol_syslog(get_only_class($this) . "::update " . $this->error, LOG_ERR);
978
                            $error++;
979
                        }
980
                    } elseif ($result < 0) {
981
                        $this->error = $lthirdparty->error;
982
                        $error++;
983
                    }
984
                }
985
            }
986
987
            if (!$error && !$notrigger) {
988
                // Call trigger
989
                $result = $this->call_trigger('MEMBER_MODIFY', $user);
990
                if ($result < 0) {
991
                    $error++;
992
                }
993
                // End call triggers
994
            }
995
996
            if (!$error) {
997
                $this->db->commit();
998
                return $nbrowsaffected;
999
            } else {
1000
                $this->db->rollback();
1001
                return -1;
1002
            }
1003
        } else {
1004
            $this->db->rollback();
1005
            $this->error = $this->db->lasterror();
1006
            return -2;
1007
        }
1008
    }
1009
1010
1011
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1012
    /**
1013
     *  Update denormalized last subscription date.
1014
     *  This function is called when we delete a subscription for example.
1015
     *
1016
     *  @param  User    $user           User making change
1017
     *  @return int                     Return integer <0 if KO, >0 if OK
1018
     */
1019
    public function update_end_date($user)
1020
    {
1021
		// phpcs:enable
1022
        $this->db->begin();
1023
1024
        // Search for last subscription id and end date
1025
        $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
1026
        $sql .= " FROM " . MAIN_DB_PREFIX . "subscription";
1027
        $sql .= " WHERE fk_adherent = " . ((int) $this->id);
1028
        $sql .= " ORDER by dateadh DESC"; // Sort by start subscription date
1029
1030
        dol_syslog(get_only_class($this) . "::update_end_date", LOG_DEBUG);
1031
        $resql = $this->db->query($sql);
1032
        if ($resql) {
1033
            $obj = $this->db->fetch_object($resql);
1034
            $dateop = $this->db->jdate($obj->dateop);
1035
            $datedeb = $this->db->jdate($obj->datedeb);
1036
            $datefin = $this->db->jdate($obj->datefin);
1037
1038
            $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
1039
            $sql .= " datefin=" . ($datefin != '' ? "'" . $this->db->idate($datefin) . "'" : "null");
1040
            $sql .= " WHERE rowid = " . ((int) $this->id);
1041
1042
            dol_syslog(get_only_class($this) . "::update_end_date", LOG_DEBUG);
1043
            $resql = $this->db->query($sql);
1044
            if ($resql) {
1045
                $this->last_subscription_date = $dateop;
1046
                $this->last_subscription_date_start = $datedeb;
1047
                $this->last_subscription_date_end = $datefin;
1048
                $this->datefin = $datefin;
1049
                $this->db->commit();
1050
                return 1;
1051
            } else {
1052
                $this->db->rollback();
1053
                return -1;
1054
            }
1055
        } else {
1056
            $this->error = $this->db->lasterror();
1057
            $this->db->rollback();
1058
            return -1;
1059
        }
1060
    }
1061
1062
    /**
1063
     *  Fonction to delete a member and its data
1064
     *
1065
     *  @param  User    $user       User object
1066
     *  @param  int     $notrigger  1=Does not execute triggers, 0= execute triggers
1067
     *  @return int                 Return integer <0 if KO, 0=nothing to do, >0 if OK
1068
     */
1069
    public function delete($user, $notrigger = 0)
1070
    {
1071
        $result = 0;
1072
        $error = 0;
1073
        $errorflag = 0;
1074
1075
        // Check parameters
1076
        $rowid = $this->id;
1077
1078
        $this->db->begin();
1079
1080
        if (!$error && !$notrigger) {
1081
            // Call trigger
1082
            $result = $this->call_trigger('MEMBER_DELETE', $user);
1083
            if ($result < 0) {
1084
                $error++;
1085
            }
1086
            // End call triggers
1087
        }
1088
1089
        // Remove category
1090
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "categorie_member WHERE fk_member = " . ((int) $rowid);
1091
        dol_syslog(get_only_class($this) . "::delete", LOG_DEBUG);
1092
        $resql = $this->db->query($sql);
1093
        if (!$resql) {
1094
            $error++;
1095
            $this->error .= $this->db->lasterror();
1096
            $errorflag = -1;
1097
        }
1098
1099
        // Remove subscription
1100
        if (!$error) {
1101
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "subscription WHERE fk_adherent = " . ((int) $rowid);
1102
            dol_syslog(get_only_class($this) . "::delete", LOG_DEBUG);
1103
            $resql = $this->db->query($sql);
1104
            if (!$resql) {
1105
                $error++;
1106
                $this->error .= $this->db->lasterror();
1107
                $errorflag = -2;
1108
            }
1109
        }
1110
1111
        // Remove linked user
1112
        if (!$error) {
1113
            $ret = $this->setUserId(0);
1114
            if ($ret < 0) {
1115
                $error++;
1116
                $this->error .= $this->db->lasterror();
1117
                $errorflag = -3;
1118
            }
1119
        }
1120
1121
        // Removed extrafields
1122
        if (!$error) {
1123
            $result = $this->deleteExtraFields();
1124
            if ($result < 0) {
1125
                $error++;
1126
                $errorflag = -4;
1127
                dol_syslog(get_only_class($this) . "::delete erreur " . $errorflag . " " . $this->error, LOG_ERR);
1128
            }
1129
        }
1130
1131
        // Remove adherent
1132
        if (!$error) {
1133
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "adherent WHERE rowid = " . ((int) $rowid);
1134
            dol_syslog(get_only_class($this) . "::delete", LOG_DEBUG);
1135
            $resql = $this->db->query($sql);
1136
            if (!$resql) {
1137
                $error++;
1138
                $this->error .= $this->db->lasterror();
1139
                $errorflag = -5;
1140
            }
1141
        }
1142
1143
        if (!$error) {
1144
            $this->db->commit();
1145
            return 1;
1146
        } else {
1147
            $this->db->rollback();
1148
            return $errorflag;
1149
        }
1150
    }
1151
1152
1153
    /**
1154
     *    Change password of a user
1155
     *
1156
     *    @param    User    $user           Object user de l'utilisateur qui fait la modification
1157
     *    @param    string  $password       New password (to generate if empty)
1158
     *    @param    int     $isencrypted    0 ou 1 if the password needs to be encrypted in the DB (default: 0)
1159
     *    @param    int     $notrigger      1=Does not raise the triggers
1160
     *    @param    int     $nosyncuser     Do not synchronize linked user
1161
     *    @return   string|int              Clear password if change ok, 0 if no change, <0 if error
1162
     */
1163
    public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
1164
    {
1165
        global $conf, $langs;
1166
1167
        $error = 0;
1168
1169
        dol_syslog(get_only_class($this) . "::setPassword user=" . $user->id . " password=" . preg_replace('/./i', '*', $password) . " isencrypted=" . $isencrypted);
1170
1171
        // If new password not provided, we generate one
1172
        if (!$password) {
1173
            require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/security2.lib.php';
1174
            $password = getRandomPassword(false);
1175
        }
1176
1177
        // Crypt password
1178
        $password_crypted = dol_hash($password);
1179
1180
        $password_indatabase = '';
1181
        if (!$isencrypted) {
1182
            $password_indatabase = $password;
1183
        }
1184
1185
        $this->db->begin();
1186
1187
        // Mise a jour
1188
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent";
1189
        $sql .= " SET pass_crypted = '" . $this->db->escape($password_crypted) . "'";
1190
        if ($isencrypted) {
1191
            $sql .= ", pass = null";
1192
        } else {
1193
            $sql .= ", pass = '" . $this->db->escape($password_indatabase) . "'";
1194
        }
1195
        $sql .= " WHERE rowid = " . ((int) $this->id);
1196
1197
        //dol_syslog("Adherent::Password sql=hidden");
1198
        dol_syslog(get_only_class($this) . "::setPassword", LOG_DEBUG);
1199
        $result = $this->db->query($sql);
1200
        if ($result) {
1201
            $nbaffectedrows = $this->db->affected_rows($result);
1202
1203
            if ($nbaffectedrows) {
1204
                $this->pass = $password;
1205
                $this->pass_indatabase = $password_indatabase;
1206
                $this->pass_indatabase_crypted = $password_crypted;
1207
1208
                if ($this->user_id && !$nosyncuser) {
1209
                    // This member is linked with a user, so we also update users information
1210
                    // if this is an update.
1211
                    $luser = new User($this->db);
1212
                    $result = $luser->fetch($this->user_id);
1213
1214
                    if ($result >= 0) {
1215
                        $result = $luser->setPassword($user, $this->pass, 0, 0, 1);
1216
                        if (is_int($result) && $result < 0) {
1217
                            $this->error = $luser->error;
1218
                            dol_syslog(get_only_class($this) . "::setPassword " . $this->error, LOG_ERR);
1219
                            $error++;
1220
                        }
1221
                    } else {
1222
                        $this->error = $luser->error;
1223
                        $error++;
1224
                    }
1225
                }
1226
1227
                if (!$error && !$notrigger) {
1228
                    // Call trigger
1229
                    $result = $this->call_trigger('MEMBER_NEW_PASSWORD', $user);
1230
                    if ($result < 0) {
1231
                        $error++;
1232
                        $this->db->rollback();
1233
                        return -1;
1234
                    }
1235
                    // End call triggers
1236
                }
1237
1238
                $this->db->commit();
1239
                return $this->pass;
1240
            } else {
1241
                $this->db->rollback();
1242
                return 0;
1243
            }
1244
        } else {
1245
            $this->db->rollback();
1246
            dol_print_error($this->db);
1247
            return -1;
1248
        }
1249
    }
1250
1251
1252
    /**
1253
     *    Set link to a user
1254
     *
1255
     *    @param     int    $userid         Id of user to link to
1256
     *    @return    int                    1=OK, -1=KO
1257
     */
1258
    public function setUserId($userid)
1259
    {
1260
        global $conf, $langs;
1261
1262
        $this->db->begin();
1263
1264
        // If user is linked to this member, remove old link to this member
1265
        $sql = "UPDATE " . MAIN_DB_PREFIX . "user SET fk_member = NULL WHERE fk_member = " . ((int) $this->id);
1266
        dol_syslog(get_only_class($this) . "::setUserId", LOG_DEBUG);
1267
        $resql = $this->db->query($sql);
1268
        if (!$resql) {
1269
            $this->error = $this->db->error();
1270
            $this->db->rollback();
1271
            return -1;
1272
        }
1273
1274
        // Set link to user
1275
        if ($userid > 0) {
1276
            $sql = "UPDATE " . MAIN_DB_PREFIX . "user SET fk_member = " . ((int) $this->id);
1277
            $sql .= " WHERE rowid = " . ((int) $userid);
1278
            dol_syslog(get_only_class($this) . "::setUserId", LOG_DEBUG);
1279
            $resql = $this->db->query($sql);
1280
            if (!$resql) {
1281
                $this->error = $this->db->error();
1282
                $this->db->rollback();
1283
                return -2;
1284
            }
1285
        }
1286
1287
        $this->db->commit();
1288
1289
        return 1;
1290
    }
1291
1292
1293
    /**
1294
     *    Set link to a third party
1295
     *
1296
     *    @param     int    $thirdpartyid       Id of user to link to
1297
     *    @return    int                        1=OK, -1=KO
1298
     */
1299
    public function setThirdPartyId($thirdpartyid)
1300
    {
1301
        global $conf, $langs;
1302
1303
        $this->db->begin();
1304
1305
        // Remove link to third party onto any other members
1306
        if ($thirdpartyid > 0) {
1307
            $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET fk_soc = null";
1308
            $sql .= " WHERE fk_soc = " . ((int) $thirdpartyid);
1309
            $sql .= " AND entity = " . $conf->entity;
1310
            dol_syslog(get_only_class($this) . "::setThirdPartyId", LOG_DEBUG);
1311
            $resql = $this->db->query($sql);
1312
        }
1313
1314
        // Add link to third party for current member
1315
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET fk_soc = " . ($thirdpartyid > 0 ? (int) $thirdpartyid : 'null');
1316
        $sql .= " WHERE rowid = " . ((int) $this->id);
1317
1318
        dol_syslog(get_only_class($this) . "::setThirdPartyId", LOG_DEBUG);
1319
        $resql = $this->db->query($sql);
1320
        if ($resql) {
1321
            $this->db->commit();
1322
            return 1;
1323
        } else {
1324
            $this->error = $this->db->error();
1325
            $this->db->rollback();
1326
            return -1;
1327
        }
1328
    }
1329
1330
1331
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1332
    /**
1333
     *  Method to load member from its login
1334
     *
1335
     *  @param  string  $login      login of member
1336
     *  @return void
1337
     */
1338
    public function fetch_login($login)
1339
    {
1340
		// phpcs:enable
1341
        global $conf;
1342
1343
        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "adherent";
1344
        $sql .= " WHERE login='" . $this->db->escape($login) . "'";
1345
        $sql .= " AND entity = " . $conf->entity;
1346
1347
        $resql = $this->db->query($sql);
1348
        if ($resql) {
1349
            if ($this->db->num_rows($resql)) {
1350
                $obj = $this->db->fetch_object($resql);
1351
                $this->fetch($obj->rowid);
1352
            }
1353
        } else {
1354
            dol_print_error($this->db);
1355
        }
1356
    }
1357
1358
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1359
    /**
1360
     *  Method to load member from its name
1361
     *
1362
     *  @param  string  $firstname  Firstname
1363
     *  @param  string  $lastname   Lastname
1364
     *  @return void
1365
     */
1366
    public function fetch_name($firstname, $lastname)
1367
    {
1368
		// phpcs:enable
1369
        global $conf;
1370
1371
        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "adherent";
1372
        $sql .= " WHERE firstname='" . $this->db->escape($firstname) . "'";
1373
        $sql .= " AND lastname='" . $this->db->escape($lastname) . "'";
1374
        $sql .= " AND entity = " . $conf->entity;
1375
1376
        $resql = $this->db->query($sql);
1377
        if ($resql) {
1378
            if ($this->db->num_rows($resql)) {
1379
                $obj = $this->db->fetch_object($resql);
1380
                $this->fetch($obj->rowid);
1381
            }
1382
        } else {
1383
            dol_print_error($this->db);
1384
        }
1385
    }
1386
1387
    /**
1388
     *  Load member from database
1389
     *
1390
     *  @param  int     $rowid                  Id of object to load
1391
     *  @param  string  $ref                    To load member from its ref
1392
     *  @param  int     $fk_soc                 To load member from its link to third party
1393
     *  @param  string  $ref_ext                External reference
1394
     *  @param  bool    $fetch_optionals        To load optionals (extrafields)
1395
     *  @param  bool    $fetch_subscriptions    To load member subscriptions
1396
     *  @return int                             >0 if OK, 0 if not found, <0 if KO
1397
     */
1398
    public function fetch($rowid, $ref = '', $fk_soc = 0, $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
1399
    {
1400
        global $langs;
1401
1402
        $sql = "SELECT d.rowid, d.ref, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname,";
1403
        $sql .= " d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1404
        $sql .= " d.note_public,";
1405
        $sql .= " d.email, d.url, d.socialnetworks, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1406
        $sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1407
        $sql .= " d.datec as datec,";
1408
        $sql .= " d.tms as datem,";
1409
        $sql .= " d.datefin as datefin, d.default_lang,";
1410
        $sql .= " d.birth as birthday,";
1411
        $sql .= " d.datevalid as datev,";
1412
        $sql .= " d.country,";
1413
        $sql .= " d.state_id,";
1414
        $sql .= " d.model_pdf,";
1415
        $sql .= " c.rowid as country_id, c.code as country_code, c.label as country,";
1416
        $sql .= " dep.nom as state, dep.code_departement as state_code,";
1417
        $sql .= " t.libelle as type, t.subscription as subscription,";
1418
        $sql .= " u.rowid as user_id, u.login as user_login";
1419
        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent_type as t, " . MAIN_DB_PREFIX . "adherent as d";
1420
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_country as c ON d.country = c.rowid";
1421
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_departements as dep ON d.state_id = dep.rowid";
1422
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as u ON d.rowid = u.fk_member";
1423
        $sql .= " WHERE d.fk_adherent_type = t.rowid";
1424
        if ($rowid) {
1425
            $sql .= " AND d.rowid=" . ((int) $rowid);
1426
        } elseif ($ref || $fk_soc) {
1427
            $sql .= " AND d.entity IN (" . getEntity('adherent') . ")";
1428
            if ($ref) {
1429
                $sql .= " AND d.ref='" . $this->db->escape($ref) . "'";
1430
            } elseif ($fk_soc > 0) {
1431
                $sql .= " AND d.fk_soc=" . ((int) $fk_soc);
1432
            }
1433
        } elseif ($ref_ext) {
1434
            $sql .= " AND d.ref_ext='" . $this->db->escape($ref_ext) . "'";
1435
        }
1436
1437
        dol_syslog(get_only_class($this) . "::fetch", LOG_DEBUG);
1438
        $resql = $this->db->query($sql);
1439
        if ($resql) {
1440
            if ($this->db->num_rows($resql)) {
1441
                $obj = $this->db->fetch_object($resql);
1442
1443
                $this->entity = $obj->entity;
1444
                $this->id = $obj->rowid;
1445
                $this->ref = $obj->ref;
1446
                $this->ref_ext = $obj->ref_ext;
1447
1448
                $this->civility_id = $obj->civility_code; // Bad. Kept for backward compatibility
1449
                $this->civility_code = $obj->civility_code;
1450
                $this->civility = $obj->civility_code ? ($langs->trans("Civility" . $obj->civility_code) != "Civility" . $obj->civility_code ? $langs->trans("Civility" . $obj->civility_code) : $obj->civility_code) : '';
1451
1452
                $this->firstname = $obj->firstname;
1453
                $this->lastname = $obj->lastname;
1454
                $this->gender = $obj->gender;
1455
                $this->login = $obj->login;
1456
                $this->societe = $obj->company;
1457
                $this->company = $obj->company;
1458
                $this->socid = $obj->fk_soc;
1459
                $this->fk_soc = $obj->fk_soc; // For backward compatibility
1460
                $this->address = $obj->address;
1461
                $this->zip = $obj->zip;
1462
                $this->town = $obj->town;
1463
1464
                $this->pass = $obj->pass;
1465
                $this->pass_indatabase = $obj->pass;
1466
                $this->pass_indatabase_crypted = $obj->pass_crypted;
1467
1468
                $this->state_id = $obj->state_id;
1469
                $this->state_code = $obj->state_id ? $obj->state_code : '';
1470
                $this->state = $obj->state_id ? $obj->state : '';
1471
1472
                $this->country_id = $obj->country_id;
1473
                $this->country_code = $obj->country_code;
1474
                if ($langs->trans("Country" . $obj->country_code) != "Country" . $obj->country_code) {
1475
                    $this->country = $langs->transnoentitiesnoconv("Country" . $obj->country_code);
1476
                } else {
1477
                    $this->country = $obj->country;
1478
                }
1479
1480
                $this->phone = $obj->phone;
1481
                $this->phone_perso = $obj->phone_perso;
1482
                $this->phone_mobile = $obj->phone_mobile;
1483
                $this->email = $obj->email;
1484
                $this->url = $obj->url;
1485
1486
                $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1487
1488
                $this->photo = $obj->photo;
1489
                $this->statut = $obj->statut;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1489
                /** @scrutinizer ignore-deprecated */ $this->statut = $obj->statut;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1490
                $this->status = $obj->statut;
1491
                $this->public = $obj->public;
1492
1493
                $this->datec = $this->db->jdate($obj->datec);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->db->jdate($obj->datec) can also be of type string. However, the property $datec is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1494
                $this->date_creation = $this->db->jdate($obj->datec);
1495
                $this->datem = $this->db->jdate($obj->datem);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->db->jdate($obj->datem) can also be of type string. However, the property $datem is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1496
                $this->date_modification = $this->db->jdate($obj->datem);
1497
                $this->datefin = $this->db->jdate($obj->datefin);
1498
                $this->datevalid = $this->db->jdate($obj->datev);
1499
                $this->date_validation = $this->db->jdate($obj->datev);
1500
                $this->birth = $this->db->jdate($obj->birthday);
1501
1502
                $this->default_lang = $obj->default_lang;
1503
1504
                $this->note_private = $obj->note_private;
1505
                $this->note_public = $obj->note_public;
1506
                $this->morphy = $obj->morphy;
1507
1508
                $this->typeid = $obj->fk_adherent_type;
1509
                $this->type = $obj->type;
1510
                $this->need_subscription = $obj->subscription;
1511
1512
                $this->user_id = $obj->user_id;
1513
                $this->user_login = $obj->user_login;
1514
1515
                $this->model_pdf = $obj->model_pdf;
1516
1517
                // Retrieve all extrafield
1518
                // fetch optionals attributes and labels
1519
                if ($fetch_optionals) {
1520
                    $this->fetch_optionals();
1521
                }
1522
1523
                // Load other properties
1524
                if ($fetch_subscriptions) {
1525
                    $result = $this->fetch_subscriptions();
1526
                }
1527
1528
                return $this->id;
1529
            } else {
1530
                return 0;
1531
            }
1532
        } else {
1533
            $this->error = $this->db->lasterror();
1534
            return -1;
1535
        }
1536
    }
1537
1538
1539
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1540
    /**
1541
     *  Function to get member subscriptions data:
1542
     *  subscriptions,
1543
     *  first_subscription_date, first_subscription_date_start, first_subscription_date_end, first_subscription_amount
1544
     *  last_subscription_date, last_subscription_date_start, last_subscription_date_end, last_subscription_amount
1545
     *
1546
     *  @return     int         Return integer <0 if KO, >0 if OK
1547
     */
1548
    public function fetch_subscriptions()
1549
    {
1550
		// phpcs:enable
1551
        global $langs;
1552
1553
1554
        $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
1555
        $sql .= " c.tms as datem,";
1556
        $sql .= " c.datec as datec,";
1557
        $sql .= " c.dateadh as dateh,";
1558
        $sql .= " c.datef as datef";
1559
        $sql .= " FROM " . MAIN_DB_PREFIX . "subscription as c";
1560
        $sql .= " WHERE c.fk_adherent = " . ((int) $this->id);
1561
        $sql .= " ORDER BY c.dateadh";
1562
        dol_syslog(get_only_class($this) . "::fetch_subscriptions", LOG_DEBUG);
1563
1564
        $resql = $this->db->query($sql);
1565
        if ($resql) {
1566
            $this->subscriptions = array();
1567
1568
            $i = 0;
1569
            while ($obj = $this->db->fetch_object($resql)) {
1570
                if ($i == 0) {
1571
                    $this->first_subscription_date = $this->db->jdate($obj->datec);
1572
                    $this->first_subscription_date_start = $this->db->jdate($obj->dateh);
1573
                    $this->first_subscription_date_end = $this->db->jdate($obj->datef);
1574
                    $this->first_subscription_amount = $obj->subscription;
1575
                }
1576
                $this->last_subscription_date = $this->db->jdate($obj->datec);
1577
                $this->last_subscription_date_start = $this->db->jdate($obj->dateh);
1578
                $this->last_subscription_date_end = $this->db->jdate($obj->datef);
1579
                $this->last_subscription_amount = $obj->subscription;
1580
1581
                $subscription = new Subscription($this->db);
1582
                $subscription->id = $obj->rowid;
1583
                $subscription->fk_adherent = $obj->fk_adherent;
1584
                $subscription->fk_type = $obj->fk_type;
1585
                $subscription->amount = $obj->subscription;
1586
                $subscription->note = $obj->note_public;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$note has been deprecated: Use $note_private instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1586
                /** @scrutinizer ignore-deprecated */ $subscription->note = $obj->note_public;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1587
                $subscription->note_public = $obj->note_public;
1588
                $subscription->fk_bank = $obj->fk_bank;
1589
                $subscription->datem = $this->db->jdate($obj->datem);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->db->jdate($obj->datem) can also be of type string. However, the property $datem is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1590
                $subscription->datec = $this->db->jdate($obj->datec);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->db->jdate($obj->datec) can also be of type string. However, the property $datec is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1591
                $subscription->dateh = $this->db->jdate($obj->dateh);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->db->jdate($obj->dateh) can also be of type string. However, the property $dateh is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1592
                $subscription->datef = $this->db->jdate($obj->datef);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->db->jdate($obj->datef) can also be of type string. However, the property $datef is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1593
1594
                $this->subscriptions[] = $subscription;
1595
1596
                $i++;
1597
            }
1598
            return 1;
1599
        } else {
1600
            $this->error = $this->db->error() . ' sql=' . $sql;
1601
            return -1;
1602
        }
1603
    }
1604
1605
1606
    /**
1607
     *  Function to get partnerships array
1608
     *
1609
     *  @param      string      $mode       'member' or 'thirdparty'
1610
     *  @return     int                     Return integer <0 if KO, >0 if OK
1611
     */
1612
    public function fetchPartnerships($mode)
1613
    {
1614
        global $langs;
1615
1616
        $this->partnerships[] = array();
1617
1618
        return 1;
1619
    }
1620
1621
1622
    /**
1623
     *  Insert subscription into database and eventually add links to banks, mailman, etc...
1624
     *
1625
     *  @param  int         $date               Date of effect of subscription
1626
     *  @param  double      $amount             Amount of subscription (0 accepted for some members)
1627
     *  @param  int         $accountid          Id bank account. NOT USED.
1628
     *  @param  string      $operation          Code of payment mode (if Id bank account provided). Example: 'CB', ... NOT USED.
1629
     *  @param  string      $label              Label operation (if Id bank account provided).
1630
     *  @param  string      $num_chq            Numero cheque (if Id bank account provided)
1631
     *  @param  string      $emetteur_nom       Name of cheque writer
1632
     *  @param  string      $emetteur_banque    Name of bank of cheque
1633
     *  @param  int         $datesubend         Date end subscription
1634
     *  @param  int         $fk_type            Member type id
1635
     *  @return int                             rowid of record added, <0 if KO
1636
     */
1637
    public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
1638
    {
1639
        global $conf, $langs, $user;
1640
1641
1642
        $error = 0;
1643
1644
        // Clean parameters
1645
        if (!$amount) {
1646
            $amount = 0;
1647
        }
1648
1649
        $this->db->begin();
1650
1651
        if ($datesubend) {
1652
            $datefin = $datesubend;
1653
        } else {
1654
            // If no end date, end date = date + 1 year - 1 day
1655
            $datefin = dol_time_plus_duree($date, 1, 'y');
1656
            $datefin = dol_time_plus_duree($datefin, -1, 'd');
1657
        }
1658
1659
        // Create subscription
1660
        $subscription = new Subscription($this->db);
1661
        $subscription->fk_adherent = $this->id;
1662
        $subscription->dateh = $date; // Date of new subscription
1663
        $subscription->datef = $datefin; // End data of new subscription
1664
        $subscription->amount = $amount;
1665
        $subscription->note = $label; // deprecated
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$note has been deprecated: Use $note_private instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1665
        /** @scrutinizer ignore-deprecated */ $subscription->note = $label; // deprecated

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1666
        $subscription->note_public = $label;
1667
        $subscription->fk_type = $fk_type;
1668
1669
        $rowid = $subscription->create($user);
1670
        if ($rowid > 0) {
1671
            // Update denormalized subscription end date (read database subscription to find values)
1672
            // This will also update this->datefin
1673
            $result = $this->update_end_date($user);
1674
            if ($result > 0) {
1675
                // Change properties of object (used by triggers)
1676
                $this->last_subscription_date = dol_now();
1677
                $this->last_subscription_date_start = $date;
1678
                $this->last_subscription_date_end = $datefin;
1679
                $this->last_subscription_amount = $amount;
1680
            }
1681
1682
            if (!$error) {
1683
                $this->db->commit();
1684
                return $rowid;
1685
            } else {
1686
                $this->db->rollback();
1687
                return -2;
1688
            }
1689
        } else {
1690
            $this->setErrorsFromObject($subscription);
1691
            $this->db->rollback();
1692
            return -1;
1693
        }
1694
    }
1695
1696
1697
    /**
1698
     *  Do complementary actions after subscription recording.
1699
     *
1700
     *  @param  int         $subscriptionid         Id of created subscription
1701
     *  @param  string      $option                 Which action ('bankdirect', 'bankviainvoice', 'invoiceonly', ...)
1702
     *  @param  int         $accountid              Id bank account
1703
     *  @param  int         $datesubscription       Date of subscription
1704
     *  @param  int         $paymentdate            Date of payment
1705
     *  @param  string      $operation              Code of type of operation (if Id bank account provided). Example 'CB', ...
1706
     *  @param  string      $label                  Label operation (if Id bank account provided)
1707
     *  @param  double      $amount                 Amount of subscription (0 accepted for some members)
1708
     *  @param  string      $num_chq                Numero cheque (if Id bank account provided)
1709
     *  @param  string      $emetteur_nom           Name of cheque writer
1710
     *  @param  string      $emetteur_banque        Name of bank of cheque
1711
     *  @param  int         $autocreatethirdparty   Auto create new thirdparty if member not yet linked to a thirdparty and we request an option that generate invoice.
1712
     *  @param  string      $ext_payment_id         External id of payment (for example Stripe charge id)
1713
     *  @param  string      $ext_payment_site       Name of external paymentmode (for example 'stripe')
1714
     *  @return int                                 Return integer <0 if KO, >0 if OK
1715
     */
1716
    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 = '')
1717
    {
1718
        global $conf, $langs, $user, $mysoc;
1719
1720
        $error = 0;
1721
1722
        $this->invoice = null; // This will contains invoice if an invoice is created
1723
1724
        dol_syslog("subscriptionComplementaryActions subscriptionid=" . $subscriptionid . " option=" . $option . " accountid=" . $accountid . " datesubscription=" . $datesubscription . " paymentdate=" .
1725
            $paymentdate . " label=" . $label . " amount=" . $amount . " num_chq=" . $num_chq . " autocreatethirdparty=" . $autocreatethirdparty);
1726
1727
        // Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
1728
        if ($option == 'bankdirect' && $accountid) {
1729
            $acct = new Account($this->db);
1730
            $result = $acct->fetch($accountid);
1731
1732
            $dateop = $paymentdate;
1733
1734
            $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, '', $user, $emetteur_nom, $emetteur_banque);
1735
            if ($insertid > 0) {
1736
                $inserturlid = $acct->add_url_line($insertid, $this->id, constant('BASE_URL') . '/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
1737
                if ($inserturlid > 0) {
1738
                    // Update table subscription
1739
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "subscription SET fk_bank=" . ((int) $insertid);
1740
                    $sql .= " WHERE rowid=" . ((int) $subscriptionid);
1741
1742
                    dol_syslog("subscription::subscription", LOG_DEBUG);
1743
                    $resql = $this->db->query($sql);
1744
                    if (!$resql) {
1745
                        $error++;
1746
                        $this->error = $this->db->lasterror();
1747
                        $this->errors[] = $this->error;
1748
                    }
1749
                } else {
1750
                    $error++;
1751
                    $this->setErrorsFromObject($acct);
1752
                }
1753
            } else {
1754
                $error++;
1755
                $this->setErrorsFromObject($acct);
1756
            }
1757
        }
1758
1759
        // If option chosen, we create invoice
1760
        if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
1761
            $invoice = new Facture($this->db);
1762
            $customer = new Societe($this->db);
1763
1764
            if (!$error) {
1765
                if (!($this->fk_soc > 0)) { // If not yet linked to a company
1766
                    if ($autocreatethirdparty) {
1767
                        // Create a linked thirdparty to member
1768
                        $companyalias = '';
1769
                        $fullname = $this->getFullName($langs);
1770
1771
                        if ($this->morphy == 'mor') {
1772
                            $companyname = $this->company;
1773
                            if (!empty($fullname)) {
1774
                                $companyalias = $fullname;
1775
                            }
1776
                        } else {
1777
                            $companyname = $fullname;
1778
                            if (!empty($this->company)) {
1779
                                $companyalias = $this->company;
1780
                            }
1781
                        }
1782
1783
                        $result = $customer->create_from_member($this, $companyname, $companyalias);
1784
                        if ($result < 0) {
1785
                            $this->error = $customer->error;
1786
                            $this->errors = $customer->errors;
1787
                            $error++;
1788
                        } else {
1789
                            $this->fk_soc = $result;
1790
                        }
1791
                    } else {
1792
                        $langs->load("errors");
1793
                        $this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1794
                        $this->errors[] = $this->error;
1795
                        $error++;
1796
                    }
1797
                }
1798
            }
1799
            if (!$error) {
1800
                $result = $customer->fetch($this->fk_soc);
1801
                if ($result <= 0) {
1802
                    $this->error = $customer->error;
1803
                    $this->errors = $customer->errors;
1804
                    $error++;
1805
                }
1806
            }
1807
1808
            if (!$error) {
1809
                // Create draft invoice
1810
                $invoice->type = Facture::TYPE_STANDARD;
1811
                $invoice->cond_reglement_id = $customer->cond_reglement_id;
1812
                if (empty($invoice->cond_reglement_id)) {
1813
                    $paymenttermstatic = new PaymentTerm($this->db);
1814
                    $invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
1815
                    if (empty($invoice->cond_reglement_id)) {
1816
                        $error++;
1817
                        $this->error = 'ErrorNoPaymentTermRECEPFound';
1818
                        $this->errors[] = $this->error;
1819
                    }
1820
                }
1821
                $invoice->socid = $this->fk_soc;
1822
                //$invoice->date = $datesubscription;
1823
                $invoice->date = dol_now();
1824
1825
                // Possibility to add external linked objects with hooks
1826
                $invoice->linked_objects['subscription'] = $subscriptionid;
1827
                if (GETPOSTISARRAY('other_linked_objects')) {
1828
                    $invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int'));
1829
                }
1830
1831
                $result = $invoice->create($user);
1832
                if ($result <= 0) {
1833
                    $this->error = $invoice->error;
1834
                    $this->errors = $invoice->errors;
1835
                    $error++;
1836
                } else {
1837
                    $this->invoice = $invoice;
1838
                }
1839
            }
1840
1841
            if (!$error) {
1842
                // Add line to draft invoice
1843
                $idprodsubscription = 0;
1844
                if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
1845
                    $idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
1846
                }
1847
1848
                $vattouse = 0;
1849
                if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
1850
                    $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
1851
                }
1852
                //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1853
                // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1854
                $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, '', 'TTC', $amount, 1);
1855
                if ($result <= 0) {
1856
                    $this->error = $invoice->error;
1857
                    $this->errors = $invoice->errors;
1858
                    $error++;
1859
                }
1860
            }
1861
1862
            if (!$error) {
1863
                // Validate invoice
1864
                $result = $invoice->validate($user);
1865
                if ($result <= 0) {
1866
                    $this->error = $invoice->error;
1867
                    $this->errors = $invoice->errors;
1868
                    $error++;
1869
                }
1870
            }
1871
1872
            if (!$error) {
1873
                // TODO Link invoice with subscription ?
1874
            }
1875
1876
            // Add payment onto invoice
1877
            if (!$error && $option == 'bankviainvoice' && $accountid) {
1878
                require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/functions.lib.php';
1879
1880
                $amounts = array();
1881
                $amounts[$invoice->id] = (float) price2num($amount);
1882
1883
                $paiement = new Paiement($this->db);
1884
                $paiement->datepaye = $paymentdate;
1885
                $paiement->amounts = $amounts;
1886
                $paiement->paiementcode = $operation;
1887
                $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
1888
                $paiement->num_payment = $num_chq;
1889
                $paiement->note_public = $label;
1890
                $paiement->ext_payment_id = $ext_payment_id;
1891
                $paiement->ext_payment_site = $ext_payment_site;
1892
1893
                if (!$error) {
1894
                    // Create payment line for invoice
1895
                    $paiement_id = $paiement->create($user);
1896
                    if (!($paiement_id > 0)) {
1897
                        $this->error = $paiement->error;
1898
                        $this->errors = $paiement->errors;
1899
                        $error++;
1900
                    }
1901
                }
1902
1903
                if (!$error) {
1904
                    // Add transaction into bank account
1905
                    $bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
1906
                    if (!($bank_line_id > 0)) {
1907
                        $this->error = $paiement->error;
1908
                        $this->errors = $paiement->errors;
1909
                        $error++;
1910
                    }
1911
                }
1912
1913
                if (!$error && !empty($bank_line_id)) {
1914
                    // Update fk_bank into subscription table
1915
                    $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'subscription SET fk_bank=' . ((int) $bank_line_id);
1916
                    $sql .= ' WHERE rowid=' . ((int) $subscriptionid);
1917
1918
                    $result = $this->db->query($sql);
1919
                    if (!$result) {
1920
                        $error++;
1921
                    }
1922
                }
1923
1924
                if (!$error) {
1925
                    // Set invoice as paid
1926
                    $invoice->setPaid($user);
1927
                }
1928
            }
1929
1930
            if (!$error) {
1931
                // Define output language
1932
                $outputlangs = $langs;
1933
                $newlang = '';
1934
                $lang_id = GETPOST('lang_id');
1935
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
1936
                    $newlang = $lang_id;
1937
                }
1938
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1939
                    $newlang = $customer->default_lang;
1940
                }
1941
                if (!empty($newlang)) {
1942
                    $outputlangs = new Translate("", $conf);
1943
                    $outputlangs->setDefaultLang($newlang);
1944
                }
1945
                // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
1946
                //if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
1947
1948
                $invoice->generateDocument($invoice->model_pdf, $outputlangs);
1949
            }
1950
        }
1951
1952
        if ($error) {
1953
            return -1;
1954
        } else {
1955
            return 1;
1956
        }
1957
    }
1958
1959
1960
    /**
1961
     *      Function that validate a member
1962
     *
1963
     *      @param  User    $user       user adherent qui valide
1964
     *      @return int                 Return integer <0 if KO, 0 if nothing done, >0 if OK
1965
     */
1966
    public function validate($user)
1967
    {
1968
        global $langs, $conf;
1969
1970
        $error = 0;
1971
        $now = dol_now();
1972
1973
        // Check parameters
1974
        if ($this->statut == self::STATUS_VALIDATED) {
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1974
        if (/** @scrutinizer ignore-deprecated */ $this->statut == self::STATUS_VALIDATED) {

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1975
            dol_syslog(get_only_class($this) . "::validate statut of member does not allow this", LOG_WARNING);
1976
            return 0;
1977
        }
1978
1979
        $this->db->begin();
1980
1981
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
1982
        $sql .= " statut = " . self::STATUS_VALIDATED;
1983
        $sql .= ", datevalid = '" . $this->db->idate($now) . "'";
1984
        $sql .= ", fk_user_valid = " . ((int) $user->id);
1985
        $sql .= " WHERE rowid = " . ((int) $this->id);
1986
1987
        dol_syslog(get_only_class($this) . "::validate", LOG_DEBUG);
1988
        $result = $this->db->query($sql);
1989
        if ($result) {
1990
            $this->statut = self::STATUS_VALIDATED;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1990
            /** @scrutinizer ignore-deprecated */ $this->statut = self::STATUS_VALIDATED;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1991
1992
            // Call trigger
1993
            $result = $this->call_trigger('MEMBER_VALIDATE', $user);
1994
            if ($result < 0) {
1995
                $error++;
1996
                $this->db->rollback();
1997
                return -1;
1998
            }
1999
            // End call triggers
2000
2001
            $this->datevalid = $now;
2002
2003
            $this->db->commit();
2004
            return 1;
2005
        } else {
2006
            $this->error = $this->db->error();
2007
            $this->db->rollback();
2008
            return -1;
2009
        }
2010
    }
2011
2012
2013
    /**
2014
     *      Fonction qui resilie un adherent
2015
     *
2016
     *      @param  User    $user       User making change
2017
     *      @return int                 Return integer <0 if KO, >0 if OK
2018
     */
2019
    public function resiliate($user)
2020
    {
2021
        global $langs, $conf;
2022
2023
        $error = 0;
2024
2025
        // Check parameters
2026
        if ($this->statut == self::STATUS_RESILIATED) {
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2026
        if (/** @scrutinizer ignore-deprecated */ $this->statut == self::STATUS_RESILIATED) {

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2027
            dol_syslog(get_only_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2028
            return 0;
2029
        }
2030
2031
        $this->db->begin();
2032
2033
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2034
        $sql .= " statut = " . self::STATUS_RESILIATED;
2035
        $sql .= ", fk_user_valid=" . $user->id;
2036
        $sql .= " WHERE rowid = " . ((int) $this->id);
2037
2038
        $result = $this->db->query($sql);
2039
        if ($result) {
2040
            $this->statut = self::STATUS_RESILIATED;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2040
            /** @scrutinizer ignore-deprecated */ $this->statut = self::STATUS_RESILIATED;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2041
2042
            // Call trigger
2043
            $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2044
            if ($result < 0) {
2045
                $error++;
2046
                $this->db->rollback();
2047
                return -1;
2048
            }
2049
            // End call triggers
2050
2051
            $this->db->commit();
2052
            return 1;
2053
        } else {
2054
            $this->error = $this->db->error();
2055
            $this->db->rollback();
2056
            return -1;
2057
        }
2058
    }
2059
2060
    /**
2061
     *      Functiun to exclude (set adherent.status to -2) a member
2062
     *      TODO
2063
     *      A private note should be added to know why the member has been excluded
2064
     *      For historical purpose it add an "extra-subscription" type excluded
2065
     *
2066
     *      @param  User    $user       User making change
2067
     *      @return int                 Return integer <0 if KO, >0 if OK
2068
     */
2069
    public function exclude($user)
2070
    {
2071
        $error = 0;
2072
2073
        // Check parameters
2074
        if ($this->statut == self::STATUS_EXCLUDED) {
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2074
        if (/** @scrutinizer ignore-deprecated */ $this->statut == self::STATUS_EXCLUDED) {

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2075
            dol_syslog(get_only_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2076
            return 0;
2077
        }
2078
2079
        $this->db->begin();
2080
2081
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2082
        $sql .= " statut = " . self::STATUS_EXCLUDED;
2083
        $sql .= ", fk_user_valid=" . $user->id;
2084
        $sql .= " WHERE rowid = " . ((int) $this->id);
2085
2086
        $result = $this->db->query($sql);
2087
        if ($result) {
2088
            $this->statut = self::STATUS_EXCLUDED;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2088
            /** @scrutinizer ignore-deprecated */ $this->statut = self::STATUS_EXCLUDED;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2089
2090
            // Call trigger
2091
            $result = $this->call_trigger('MEMBER_EXCLUDE', $user);
2092
            if ($result < 0) {
2093
                $error++;
2094
                $this->db->rollback();
2095
                return -1;
2096
            }
2097
            // End call triggers
2098
2099
            $this->db->commit();
2100
            return 1;
2101
        } else {
2102
            $this->error = $this->db->error();
2103
            $this->db->rollback();
2104
            return -1;
2105
        }
2106
    }
2107
2108
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2109
    /**
2110
     *  Function to add member into external tools mailing-list, spip, etc.
2111
     *
2112
     *  @return     int     Return integer <0 if KO, >0 if OK
2113
     */
2114
    public function add_to_abo()
2115
    {
2116
		// phpcs:enable
2117
        global $langs;
2118
2119
        include_once DOL_DOCUMENT_ROOT . '/mailmanspip/class/mailmanspip.class.php';
2120
        $mailmanspip = new MailmanSpip($this->db);
2121
2122
        $err = 0;
2123
2124
        // mailman
2125
        if (getDolGlobalString('ADHERENT_USE_MAILMAN') && isModEnabled('mailmanspip')) {
2126
            $result = $mailmanspip->add_to_mailman($this);
2127
2128
            if ($result < 0) {
2129
                if (!empty($mailmanspip->error)) {
2130
                    $this->errors[] = $mailmanspip->error;
2131
                }
2132
                $err += 1;
2133
            }
2134
            foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) {
2135
                $langs->load("errors");
2136
                $this->errors[] = $langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
2137
            }
2138
            foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) {
2139
                $langs->load("mailmanspip");
2140
                $this->mesgs[] = $langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
2141
            }
2142
        }
2143
2144
        // spip
2145
        if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2146
            $result = $mailmanspip->add_to_spip($this);
2147
            if ($result < 0) {
2148
                $this->errors[] = $mailmanspip->error;
2149
                $err += 1;
2150
            }
2151
        }
2152
        if ($err) {
2153
            return -$err;
2154
        } else {
2155
            return 1;
2156
        }
2157
    }
2158
2159
2160
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2161
    /**
2162
     *  Function to delete a member from external tools like mailing-list, spip, etc.
2163
     *
2164
     *  @return     int     Return integer <0 if KO, >0 if OK
2165
     */
2166
    public function del_to_abo()
2167
    {
2168
		// phpcs:enable
2169
        global $conf, $langs;
2170
2171
        include_once DOL_DOCUMENT_ROOT . '/mailmanspip/class/mailmanspip.class.php';
2172
        $mailmanspip = new MailmanSpip($this->db);
2173
2174
        $err = 0;
2175
2176
        // mailman
2177
        if (getDolGlobalString('ADHERENT_USE_MAILMAN')) {
2178
            $result = $mailmanspip->del_to_mailman($this);
2179
            if ($result < 0) {
2180
                if (!empty($mailmanspip->error)) {
2181
                    $this->errors[] = $mailmanspip->error;
2182
                }
2183
                $err += 1;
2184
            }
2185
2186
            foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) {
2187
                $langs->load("errors");
2188
                $this->errors[] = $langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
2189
            }
2190
            foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) {
2191
                $langs->load("mailmanspip");
2192
                $this->mesgs[] = $langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
2193
            }
2194
        }
2195
2196
        if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
2197
            $result = $mailmanspip->del_to_spip($this);
2198
            if ($result < 0) {
2199
                $this->errors[] = $mailmanspip->error;
2200
                $err += 1;
2201
            }
2202
        }
2203
        if ($err) {
2204
            // error
2205
            return -$err;
2206
        } else {
2207
            return 1;
2208
        }
2209
    }
2210
2211
2212
    /**
2213
     *    Return civility label of a member
2214
     *
2215
     *    @return   string                  Translated name of civility (translated with transnoentitiesnoconv)
2216
     */
2217
    public function getCivilityLabel()
2218
    {
2219
        global $langs;
2220
        $langs->load("dict");
2221
2222
        $code = (empty($this->civility_id) ? '' : $this->civility_id);
2223
        if (empty($code)) {
2224
            return '';
2225
        }
2226
        return $langs->getLabelFromKey($this->db, "Civility" . $code, "c_civility", "code", "label", $code);
2227
    }
2228
2229
    /**
2230
     * getTooltipContentArray
2231
     * @param array $params params to construct tooltip data
2232
     * @since v18
2233
     * @return array
2234
     */
2235
    public function getTooltipContentArray($params)
2236
    {
2237
        global $langs;
2238
2239
        $langs->loadLangs(['members', 'companies']);
2240
        $nofetch = !empty($params['nofetch']);
2241
2242
        $datas = array();
2243
2244
        if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2245
            $langs->load("users");
2246
            return ['optimize' => $langs->trans("ShowUser")];
2247
        }
2248
        if (!empty($this->photo)) {
2249
            $photo = '<div class="photointooltip floatright">';
2250
            $photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1);
2251
            $photo .= '</div>';
2252
            $datas['photo'] = $photo;
2253
        }
2254
2255
        $datas['divopen'] = '<div class="centpercent">';
2256
        $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Member") . '</u> ' . $this->getLibStatut(4);
2257
        if (!empty($this->morphy)) {
2258
            $datas['picto'] .= '&nbsp;' . $this->getmorphylib('', 1);
2259
        }
2260
        if (!empty($this->ref)) {
2261
            $datas['ref'] = '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
2262
        }
2263
        if (!empty($this->login)) {
2264
            $datas['login'] = '<br><b>' . $langs->trans('Login') . ':</b> ' . $this->login;
2265
        }
2266
        if (!empty($this->firstname) || !empty($this->lastname)) {
2267
            $datas['name'] = '<br><b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs);
2268
        }
2269
        if (!empty($this->company)) {
2270
            $datas['company'] = '<br><b>' . $langs->trans('Company') . ':</b> ' . $this->company;
2271
        }
2272
        if (!empty($this->email)) {
2273
            $datas['email'] = '<br><b>' . $langs->trans("EMail") . ':</b> ' . $this->email;
2274
        }
2275
        $datas['address'] = '<br><b>' . $langs->trans("Address") . ':</b> ' . dol_format_address($this, 1, ' ', $langs);
2276
        // show categories for this record only in ajax to not overload lists
2277
        if (isModEnabled('category') && !$nofetch) {
2278
            $form = new Form($this->db);
2279
            $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_MEMBER, 1);
2280
        }
2281
        $datas['divclose'] = '</div>';
2282
2283
        return $datas;
2284
    }
2285
2286
    /**
2287
     *  Return clicable name (with picto eventually)
2288
     *
2289
     *  @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=???)
2290
     *  @param  int     $maxlen                     length max label
2291
     *  @param  string  $option                     Page for link ('card', 'category', 'subscription', ...)
2292
     *  @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
2293
     *  @param  string  $morecss                    Add more css on link
2294
     *  @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
2295
     *  @param  int     $notooltip                  1=Disable tooltip
2296
     *  @param  int     $addlinktonotes             1=Add link to notes
2297
     *  @return string                              Chaine avec URL
2298
     */
2299
    public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0)
2300
    {
2301
        global $conf, $langs, $hookmanager;
2302
2303
        if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpictoimg) {
2304
            $withpictoimg = 0;
2305
        }
2306
2307
        $result = '';
2308
        $linkstart = '';
2309
        $linkend = '';
2310
        $classfortooltip = 'classfortooltip';
2311
        $dataparams = '';
2312
        $params = [
2313
            'id' => $this->id,
2314
            'objecttype' => $this->element,
2315
            'option' => $option,
2316
            'nofetch' => 1,
2317
        ];
2318
        if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
2319
            $classfortooltip = 'classforajaxtooltip';
2320
            $dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"';
2321
            $label = '';
2322
        } else {
2323
            $label = implode($this->getTooltipContentArray($params));
2324
        }
2325
2326
        $url = constant('BASE_URL') . '/adherents/card.php?rowid=' . ((int) $this->id);
2327
        if ($option == 'subscription') {
2328
            $url = constant('BASE_URL') . '/adherents/subscription.php?rowid=' . ((int) $this->id);
2329
        }
2330
2331
        if ($option != 'nolink') {
2332
            // Add param to save lastsearch_values or not
2333
            $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2334
            if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
2335
                $add_save_lastsearch_values = 1;
2336
            }
2337
            if ($add_save_lastsearch_values) {
2338
                $url .= '&save_lastsearch_values=1';
2339
            }
2340
        }
2341
2342
        $linkstart .= '<a href="' . $url . '"';
2343
        $linkclose = "";
2344
        if (empty($notooltip)) {
2345
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2346
                $langs->load("users");
2347
                $label = $langs->trans("ShowUser");
2348
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
2349
            }
2350
            $linkclose .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"');
2351
            $linkclose .= $dataparams . ' class="' . $classfortooltip . ($morecss ? ' ' . $morecss : '') . '"';
2352
        }
2353
2354
        $linkstart .= $linkclose . '>';
2355
        $linkend = '</a>';
2356
2357
        $result .= $linkstart;
2358
2359
        if ($withpictoimg) {
2360
            $paddafterimage = '';
2361
            if (abs($withpictoimg) == 1 || abs($withpictoimg) == 4) {
2362
                $morecss .= ' paddingrightonly';
2363
            }
2364
            // Only picto
2365
            if ($withpictoimg > 0) {
2366
                $picto = '<span class="nopadding' . ($morecss ? ' userimg' . $morecss : '') . '">' . img_object('', 'user', $paddafterimage . ' ' . ($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1) . '</span>';
2367
            } else {
2368
                // Picto must be a photo
2369
                $picto = '<span class="nopadding' . ($morecss ? ' userimg' . $morecss : '') . '"' . ($paddafterimage ? ' ' . $paddafterimage : '') . '>';
2370
                $picto .= Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto' . (($withpictoimg == -3 || $withpictoimg == -4) ? 'small' : ''), 'mini', 0, 1);
2371
                $picto .= '</span>';
2372
            }
2373
            $result .= $picto;
2374
        }
2375
        if (($withpictoimg > -2 && $withpictoimg != 2) || $withpictoimg == -4) {
2376
            if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2377
                $result .= '<span class="nopadding valignmiddle' . ((!isset($this->statut) || $this->statut) ? '' : ' strikefordisabled') .
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2377
                $result .= '<span class="nopadding valignmiddle' . ((!isset(/** @scrutinizer ignore-deprecated */ $this->statut) || $this->statut) ? '' : ' strikefordisabled') .

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2378
                ($morecss ? ' usertext' . $morecss : '') . '">';
2379
            }
2380
            if ($mode == 'login') {
2381
                $result .= dol_trunc($this->login, $maxlen);
2382
            } elseif ($mode == 'ref') {
2383
                $result .= $this->ref;
2384
            } else {
2385
                $result .= $this->getFullName($langs, '', ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2386
            }
2387
            if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2388
                $result .= '</span>';
2389
            }
2390
        }
2391
2392
        $result .= $linkend;
2393
2394
        if ($addlinktonotes) {
2395
            if ($this->note_private) {
2396
                $notetoshow = $langs->trans("ViewPrivateNote") . ':<br>' . dol_string_nohtmltag($this->note_private, 1);
2397
                $result .= ' <span class="note inline-block">';
2398
                $result .= '<a href="' . constant('BASE_URL') . '/adherents/note.php?id=' . $this->id . '" class="classfortooltip" title="' . dol_escape_htmltag($notetoshow) . '">';
2399
                $result .= img_picto('', 'note');
2400
                $result .= '</a>';
2401
                $result .= '</span>';
2402
            }
2403
        }
2404
        global $action;
2405
        $hookmanager->initHooks(array($this->element . 'dao'));
2406
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
2407
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2408
        if ($reshook > 0) {
2409
            $result = $hookmanager->resPrint;
2410
        } else {
2411
            $result .= $hookmanager->resPrint;
2412
        }
2413
        return $result;
2414
    }
2415
2416
    /**
2417
     *  Retourne le libelle du statut d'un adherent (brouillon, valide, resilie, exclu)
2418
     *
2419
     *  @param  int     $mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
2420
     *  @return string              Label
2421
     */
2422
    public function getLibStatut($mode = 0)
2423
    {
2424
        return $this->LibStatut($this->statut, $this->need_subscription, $this->datefin, $mode);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2424
        return $this->LibStatut(/** @scrutinizer ignore-deprecated */ $this->statut, $this->need_subscription, $this->datefin, $mode);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2425
    }
2426
2427
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2428
    /**
2429
     *  Renvoi le libelle d'un statut donne
2430
     *
2431
     *  @param  int         $status                 Id status
2432
     *  @param  int         $need_subscription      1 if member type need subscription, 0 otherwise
2433
     *  @param  int         $date_end_subscription  Date fin adhesion
2434
     *  @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
2435
     *  @return string                              Label
2436
     */
2437
    public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
2438
    {
2439
		// phpcs:enable
2440
        global $langs;
2441
        $langs->load("members");
2442
2443
        $statusType = '';
2444
        $labelStatus = '';
2445
        $labelStatusShort = '';
2446
2447
        if ($status == self::STATUS_DRAFT) {
2448
            $statusType = 'status0';
2449
            $labelStatus = $langs->trans("MemberStatusDraft");
2450
            $labelStatusShort = $langs->trans("MemberStatusDraftShort");
2451
        } elseif ($status >= self::STATUS_VALIDATED) {
2452
            if ($need_subscription === 0) {
2453
                $statusType = 'status4';
2454
                $labelStatus = $langs->trans("Validated") . ' - ' . $langs->trans("MemberStatusNoSubscription");
2455
                $labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
2456
            } elseif (!$date_end_subscription) {
2457
                $statusType = 'status1';
2458
                $labelStatus = $langs->trans("Validated") . ' - ' . $langs->trans("WaitingSubscription");
2459
                $labelStatusShort = $langs->trans("WaitingSubscriptionShort");
2460
            } elseif ($date_end_subscription < dol_now()) { // expired
2461
                $statusType = 'status8';
2462
                $labelStatus = $langs->trans("Validated") . ' - ' . $langs->trans("MemberStatusActiveLate");
2463
                $labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
2464
            } else {
2465
                $statusType = 'status4';
2466
                $labelStatus = $langs->trans("Validated") . ' - ' . $langs->trans("MemberStatusPaid");
2467
                $labelStatusShort = $langs->trans("MemberStatusPaidShort");
2468
            }
2469
        } elseif ($status == self::STATUS_RESILIATED) {
2470
            $statusType = 'status6';
2471
            $labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
2472
            $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
2473
        } elseif ($status == self::STATUS_EXCLUDED) {
2474
            $statusType = 'status10';
2475
            $labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
2476
            $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
2477
        }
2478
2479
        return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
2480
    }
2481
2482
2483
    /**
2484
     *      Load indicators this->nb in state board
2485
     *
2486
     *      @return     int         Return integer <0 if KO, >0 if OK
2487
     */
2488
    public function loadStateBoard()
2489
    {
2490
        global $conf;
2491
2492
        $this->nb = array();
2493
2494
        $sql = "SELECT count(a.rowid) as nb";
2495
        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent as a";
2496
        $sql .= " WHERE a.statut > 0";
2497
        $sql .= " AND a.entity IN (" . getEntity('adherent') . ")";
2498
2499
        $resql = $this->db->query($sql);
2500
        if ($resql) {
2501
            while ($obj = $this->db->fetch_object($resql)) {
2502
                $this->nb["members"] = $obj->nb;
2503
            }
2504
            $this->db->free($resql);
2505
            return 1;
2506
        } else {
2507
            dol_print_error($this->db);
2508
            $this->error = $this->db->error();
2509
            return -1;
2510
        }
2511
    }
2512
2513
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2514
    /**
2515
     *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
2516
     *
2517
     *      @param  User    $user           Object user
2518
     *      @param  string  $mode           "expired" for membership to renew, "shift" for member to validate
2519
     *      @return WorkboardResponse|int   Return integer <0 if KO, WorkboardResponse if OK
2520
     */
2521
    public function load_board($user, $mode)
2522
    {
2523
		// phpcs:enable
2524
        global $conf, $langs;
2525
2526
        if ($user->socid) {
2527
            return -1; // protection pour eviter appel par utilisateur externe
2528
        }
2529
2530
        $now = dol_now();
2531
2532
        $sql = "SELECT a.rowid, a.datefin, a.statut";
2533
        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent as a";
2534
        $sql .= ", " . MAIN_DB_PREFIX . "adherent_type as t";
2535
        $sql .= " WHERE a.fk_adherent_type = t.rowid";
2536
        if ($mode == 'expired') {
2537
            $sql .= " AND a.statut = " . self::STATUS_VALIDATED;
2538
            $sql .= " AND a.entity IN (" . getEntity('adherent') . ")";
2539
            $sql .= " AND ((a.datefin IS NULL or a.datefin < '" . $this->db->idate($now) . "') AND t.subscription = '1')";
2540
        } elseif ($mode == 'shift') {
2541
            $sql .= " AND a.statut = " . self::STATUS_DRAFT;
2542
            $sql .= " AND a.entity IN (" . getEntity('adherent') . ")";
2543
        }
2544
2545
        $resql = $this->db->query($sql);
2546
        if ($resql) {
2547
            $langs->load("members");
2548
2549
            $warning_delay = 0;
2550
            $url = '';
2551
            $label = '';
2552
            $labelShort = '';
2553
2554
            if ($mode == 'expired') {
2555
                $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2556
                $label = $langs->trans("MembersWithSubscriptionToReceive");
2557
                $labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
2558
                $url = constant('BASE_URL') . '/adherents/list.php?mainmenu=members&amp;statut=' . self::STATUS_VALIDATED . '&amp;filter=outofdate';
2559
            } elseif ($mode == 'shift') {
2560
                $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2561
                $url = constant('BASE_URL') . '/adherents/list.php?mainmenu=members&amp;statut=' . self::STATUS_DRAFT;
2562
                $label = $langs->trans("MembersListToValid");
2563
                $labelShort = $langs->trans("ToValidate");
2564
            }
2565
2566
            $response = new WorkboardResponse();
2567
            $response->warning_delay = $warning_delay;
2568
            $response->label = $label;
2569
            $response->labelShort = $labelShort;
2570
            $response->url = $url;
2571
            $response->img = img_object('', "user");
2572
2573
            $adherentstatic = new Adherent($this->db);
2574
2575
            while ($obj = $this->db->fetch_object($resql)) {
2576
                $response->nbtodo++;
2577
2578
                $adherentstatic->datefin = $this->db->jdate($obj->datefin);
2579
                $adherentstatic->statut = $obj->statut;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2579
                /** @scrutinizer ignore-deprecated */ $adherentstatic->statut = $obj->statut;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2580
2581
                if ($adherentstatic->hasDelay()) {
2582
                    $response->nbtodolate++;
2583
                }
2584
            }
2585
2586
            return $response;
2587
        } else {
2588
            dol_print_error($this->db);
2589
            $this->error = $this->db->error();
2590
            return -1;
2591
        }
2592
    }
2593
2594
2595
    /**
2596
     *  Create a document onto disk according to template module.
2597
     *
2598
     *  @param      string      $modele         Force template to use ('' to not force)
2599
     *  @param      Translate   $outputlangs    object lang a utiliser pour traduction
2600
     *  @param      int         $hidedetails    Hide details of lines
2601
     *  @param      int         $hidedesc       Hide description
2602
     *  @param      int         $hideref        Hide ref
2603
     *  @param   null|array  $moreparams     Array to provide more information
2604
     *  @return     int                         0 if KO, 1 if OK
2605
     */
2606
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2607
    {
2608
        global $conf, $langs;
2609
2610
        $langs->load("orders");
2611
2612
        if (!dol_strlen($modele)) {
2613
            $modele = 'standard';
2614
2615
            if ($this->model_pdf) {
2616
                $modele = $this->model_pdf;
2617
            } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2618
                $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2619
            }
2620
        }
2621
2622
        $modelpath = "core/modules/member/doc/";
2623
2624
        return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2625
    }
2626
2627
2628
    /**
2629
     *  Initialise an instance with random values.
2630
     *  Used to build previews or test instances.
2631
     *  id must be 0 if object instance is a specimen.
2632
     *
2633
     *  @return int
2634
     */
2635
    public function initAsSpecimen()
2636
    {
2637
        global $user, $langs;
2638
        $now = dol_now();
2639
2640
        // Initialise parameters
2641
        $this->id = 0;
2642
        $this->ref = 'ABC001';
2643
        $this->entity = 1;
2644
        $this->specimen = 1;
2645
        $this->civility_id = 'MR';
2646
        $this->lastname = 'DOLIBARR';
2647
        $this->firstname = 'SPECIMEN';
2648
        $this->gender = 'man';
2649
        $this->login = 'dolibspec';
2650
        $this->pass = 'dolibspec';
2651
        $this->company = 'Societe ABC';
2652
        $this->address = '61 jump street';
2653
        $this->zip = '75000';
2654
        $this->town = 'Paris';
2655
        $this->country_id = 1;
2656
        $this->country_code = 'FR';
2657
        $this->country = 'France';
2658
        $this->morphy = 'mor';
2659
        $this->email = '[email protected]';
2660
        $this->socialnetworks = array(
2661
            'skype' => 'skypepseudo',
2662
            'twitter' => 'twitterpseudo',
2663
            'facebook' => 'facebookpseudo',
2664
            'linkedin' => 'linkedinpseudo',
2665
        );
2666
        $this->phone = '0999999999';
2667
        $this->phone_perso = '0999999998';
2668
        $this->phone_mobile = '0999999997';
2669
        $this->note_public = 'This is a public note';
2670
        $this->note_private = 'This is a private note';
2671
        $this->birth = $now;
2672
        $this->photo = '';
2673
        $this->public = 1;
2674
        $this->statut = self::STATUS_DRAFT;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2674
        /** @scrutinizer ignore-deprecated */ $this->statut = self::STATUS_DRAFT;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2675
2676
        $this->datefin = $now;
2677
        $this->datevalid = $now;
2678
        $this->default_lang = '';
2679
2680
        $this->typeid = 1; // Id type adherent
2681
        $this->type = 'Type adherent'; // Libelle type adherent
2682
        $this->need_subscription = 0;
2683
2684
        $this->first_subscription_date = $now;
2685
        $this->first_subscription_date_start = $this->first_subscription_date;
2686
        $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2687
        $this->first_subscription_amount = 10;
2688
2689
        $this->last_subscription_date = $this->first_subscription_date;
2690
        $this->last_subscription_date_start = $this->first_subscription_date;
2691
        $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2692
        $this->last_subscription_amount = 10;
2693
        return 1;
2694
    }
2695
2696
2697
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2698
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2699
    /**
2700
     *  Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
2701
     *
2702
     *  @param  array   $info       Info array loaded by _load_ldap_info
2703
     *  @param  int     $mode       0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
2704
     *                              1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
2705
     *                              2=Return key only (uid=qqq)
2706
     *  @return string              DN
2707
     */
2708
    public function _load_ldap_dn($info, $mode = 0)
2709
    {
2710
		// phpcs:enable
2711
        global $conf;
2712
        $dn = '';
2713
        if ($mode == 0) {
2714
            $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=" . $info[getDolGlobalString('LDAP_KEY_MEMBERS')] . "," . getDolGlobalString('LDAP_MEMBER_DN');
2715
        }
2716
        if ($mode == 1) {
2717
            $dn = getDolGlobalString('LDAP_MEMBER_DN');
2718
        }
2719
        if ($mode == 2) {
2720
            $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=" . $info[getDolGlobalString('LDAP_KEY_MEMBERS')];
2721
        }
2722
        return $dn;
2723
    }
2724
2725
2726
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2727
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2728
    /**
2729
     *  Initialise tableau info (tableau des attributes LDAP)
2730
     *
2731
     *  @return     array       Tableau info des attributes
2732
     */
2733
    public function _load_ldap_info()
2734
    {
2735
		// phpcs:enable
2736
        global $conf, $langs;
2737
2738
        $info = array();
2739
        $socialnetworks = getArrayOfSocialNetworks();
2740
        $keymodified = false;
2741
2742
        // Object classes
2743
        $info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
2744
2745
        $this->fullname = $this->getFullName($langs);
2746
2747
        // For avoid ldap error when firstname and lastname are empty
2748
        if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
2749
            $this->fullname = $this->company;
2750
            $this->lastname = $this->company;
2751
        }
2752
2753
        // Possible LDAP KEY (constname => varname)
2754
        $ldapkey = array(
2755
            'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
2756
            'LDAP_MEMBER_FIELD_NAME' => 'lastname',
2757
            'LDAP_MEMBER_FIELD_LOGIN' => 'login',
2758
            'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
2759
            'LDAP_MEMBER_FIELD_MAIL' => 'email'
2760
        );
2761
2762
        // Member
2763
        foreach ($ldapkey as $constname => $varname) {
2764
            if (!empty($this->$varname) && getDolGlobalString($constname)) {
2765
                $info[getDolGlobalString($constname)] = $this->$varname;
2766
2767
                // Check if it is the LDAP key and if its value has been changed
2768
                if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
2769
                    if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
2770
                        $keymodified = true; // For check if LDAP key has been modified
2771
                    }
2772
                }
2773
            }
2774
        }
2775
        if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
2776
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
2777
        }
2778
        if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
2779
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
2780
        }
2781
        if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
2782
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
2783
        }
2784
        if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
2785
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
2786
        }
2787
        if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
2788
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
2789
        }
2790
        if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
2791
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
2792
        }
2793
        if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
2794
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
2795
        }
2796
        foreach ($socialnetworks as $key => $value) {
2797
            if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_' . strtoupper($value['label']))) {
2798
                $info[getDolGlobalString('LDAP_MEMBER_FIELD_' . strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
2799
            }
2800
        }
2801
        if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
2802
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
2803
        }
2804
        if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
2805
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
2806
        }
2807
        if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
2808
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
2809
        }
2810
        if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
2811
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
2812
        }
2813
        if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
2814
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
2815
        }
2816
        if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
2817
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
2818
        }
2819
        if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
2820
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
2821
        }
2822
        if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2822
        if (isset(/** @scrutinizer ignore-deprecated */ $this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2823
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
2824
        }
2825
        if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
2826
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
2827
        }
2828
2829
        // When password is modified
2830
        if (!empty($this->pass)) {
2831
            if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2832
                $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
2833
            }
2834
            if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2835
                $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2836
            }
2837
        } elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
2838
            // Set LDAP password if possible
2839
            // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2840
            if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
2841
                // Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
2842
                if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
2843
                    if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2844
                        // Create OpenLDAP MD5 password from Dolibarr MD5 password
2845
                        // Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
2846
                        $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
2847
                    }
2848
                }
2849
            } elseif (!empty($this->pass_indatabase)) {
2850
                // Use $this->pass_indatabase value if exists
2851
                if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2852
                    $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
2853
                }
2854
                if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2855
                    $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2856
                }
2857
            }
2858
        }
2859
2860
        // Subscriptions
2861
        if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
2862
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
2863
        }
2864
        if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
2865
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
2866
        }
2867
        if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
2868
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
2869
        }
2870
        if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
2871
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
2872
        }
2873
2874
        return $info;
2875
    }
2876
2877
2878
    /**
2879
     *      Load type info information in the member object
2880
     *
2881
     *      @param  int     $id       Id of member to load
2882
     *      @return void
2883
     */
2884
    public function info($id)
2885
    {
2886
        $sql = 'SELECT a.rowid, a.datec as datec,';
2887
        $sql .= ' a.datevalid as datev,';
2888
        $sql .= ' a.tms as datem,';
2889
        $sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2890
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'adherent as a';
2891
        $sql .= ' WHERE a.rowid = ' . ((int) $id);
2892
2893
        dol_syslog(get_only_class($this) . "::info", LOG_DEBUG);
2894
        $result = $this->db->query($sql);
2895
        if ($result) {
2896
            if ($this->db->num_rows($result)) {
2897
                $obj = $this->db->fetch_object($result);
2898
2899
                $this->id = $obj->rowid;
2900
2901
                $this->user_creation_id = $obj->fk_user_author;
2902
                $this->user_validation_id = $obj->fk_user_valid;
2903
                $this->user_modification_id = $obj->fk_user_mod;
2904
                $this->date_creation = $this->db->jdate($obj->datec);
2905
                $this->date_validation = $this->db->jdate($obj->datev);
2906
                $this->date_modification = $this->db->jdate($obj->datem);
2907
            }
2908
2909
            $this->db->free($result);
2910
        } else {
2911
            dol_print_error($this->db);
2912
        }
2913
    }
2914
2915
    /**
2916
     *  Return number of mass Emailing received by this member with its email
2917
     *
2918
     *  @return       int     Number of EMailings
2919
     */
2920
    public function getNbOfEMailings()
2921
    {
2922
        $sql = "SELECT count(mc.email) as nb";
2923
        $sql .= " FROM " . MAIN_DB_PREFIX . "mailing_cibles as mc";
2924
        $sql .= " WHERE mc.email = '" . $this->db->escape($this->email) . "'";
2925
        $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec success
2926
2927
        $resql = $this->db->query($sql);
2928
        if ($resql) {
2929
            $obj = $this->db->fetch_object($resql);
2930
            $nb = $obj->nb;
2931
2932
            $this->db->free($resql);
2933
            return $nb;
2934
        } else {
2935
            $this->error = $this->db->error();
2936
            return -1;
2937
        }
2938
    }
2939
2940
    /**
2941
     * Sets object to supplied categories.
2942
     *
2943
     * Deletes object from existing categories not supplied.
2944
     * Adds it to non existing supplied categories.
2945
     * Existing categories are left untouch.
2946
     *
2947
     * @param   int[]|int   $categories     Category or categories IDs
2948
     * @return  int                         Return integer <0 if KO, >0 if OK
2949
     */
2950
    public function setCategories($categories)
2951
    {
2952
        return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
2953
    }
2954
2955
    /**
2956
     * Function used to replace a thirdparty id with another one.
2957
     *
2958
     * @param DoliDB    $db             Database handler
2959
     * @param int       $origin_id      Old thirdparty id
2960
     * @param int       $dest_id        New thirdparty id
2961
     * @return bool
2962
     */
2963
    public static function replaceThirdparty($db, $origin_id, $dest_id)
2964
    {
2965
        $tables = array('adherent');
2966
2967
        return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
2968
    }
2969
2970
    /**
2971
     * Return if a member is late (subscription late) or not
2972
     *
2973
     * @return boolean     True if late, False if not late
2974
     */
2975
    public function hasDelay()
2976
    {
2977
        global $conf;
2978
2979
        //Only valid members
2980
        if ($this->statut != self::STATUS_VALIDATED) {
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

2980
        if (/** @scrutinizer ignore-deprecated */ $this->statut != self::STATUS_VALIDATED) {

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2981
            return false;
2982
        }
2983
        if (!$this->datefin) {
2984
            return false;
2985
        }
2986
2987
        $now = dol_now();
2988
2989
        return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
2990
    }
2991
2992
2993
    /**
2994
     * Send reminders by emails before subscription end
2995
     * CAN BE A CRON TASK
2996
     *
2997
     * @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'
2998
     * @return  int                                 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
2999
     */
3000
    public function sendReminderForExpiredSubscription($daysbeforeendlist = '10')
3001
    {
3002
        global $conf, $langs, $mysoc, $user;
3003
3004
        $error = 0;
3005
        $this->output = '';
3006
        $this->error = '';
3007
3008
        $blockingerrormsg = '';
3009
3010
        if (!isModEnabled('member')) { // Should not happen. If module disabled, cron job should not be visible.
3011
            $langs->load("agenda");
3012
            $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3013
            return 0;
3014
        }
3015
        if (!getDolGlobalString('MEMBER_REMINDER_EMAIL')) {
3016
            $langs->load("agenda");
3017
            $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
3018
            return 0;
3019
        }
3020
3021
        $now = dol_now();
3022
        $nbok = 0;
3023
        $nbko = 0;
3024
3025
        $listofmembersok = array();
3026
        $listofmembersko = array();
3027
3028
        $arraydaysbeforeend = explode(';', $daysbeforeendlist);
3029
        foreach ($arraydaysbeforeend as $daysbeforeend) { // Loop on each delay
3030
            dol_syslog(__METHOD__ . ' - Process delta = ' . $daysbeforeend, LOG_DEBUG);
3031
3032
            if (!is_numeric($daysbeforeend)) {
3033
                $blockingerrormsg = "Value for delta is not a numeric value";
3034
                $nbko++;
3035
                break;
3036
            }
3037
3038
            $tmp = dol_getdate($now);
3039
            $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), $daysbeforeend, 'd');
3040
3041
            $sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'adherent';
3042
            $sql .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
3043
            $sql .= " AND statut = 1";
3044
            $sql .= " AND datefin = '" . $this->db->idate($datetosearchfor) . "'";
3045
            //$sql .= " LIMIT 10000";
3046
3047
            $resql = $this->db->query($sql);
3048
            if ($resql) {
3049
                $num_rows = $this->db->num_rows($resql);
3050
3051
                $adherent = new Adherent($this->db);
3052
                $formmail = new FormMail($this->db);
3053
3054
                $i = 0;
3055
                while ($i < $num_rows) {
3056
                    $obj = $this->db->fetch_object($resql);
3057
3058
                    $adherent->fetch($obj->rowid, '', '', '', true, true);
3059
3060
                    if (empty($adherent->email)) {
3061
                        $nbko++;
3062
                        $listofmembersko[$adherent->id] = $adherent->id;
3063
                    } else {
3064
                        $adherent->fetch_thirdparty();
3065
3066
                        // 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.
3067
                        $languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : $adherent->thirdparty->country_code);
3068
                        $languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
3069
3070
                        // Send reminder email
3071
                        $outputlangs = new Translate('', $conf);
3072
                        $outputlangs->setDefaultLang($languagecodeformember);
3073
                        $outputlangs->loadLangs(array("main", "members"));
3074
                        dol_syslog("sendReminderForExpiredSubscription Language for member id " . $adherent->id . " set to " . $outputlangs->defaultlang . " mysoc->default_lang=" . $mysoc->default_lang);
3075
3076
                        $arraydefaultmessage = null;
3077
                        $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
3078
3079
                        if (!empty($labeltouse)) {
3080
                            $arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
3081
                        }
3082
3083
                        if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
3084
                            $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
3085
                            //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
3086
                            complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
3087
3088
                            $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
3089
                            $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
3090
                            $from = getDolGlobalString('ADHERENT_MAIL_FROM');
3091
                            $to = $adherent->email;
3092
                            $cc = getDolGlobalString('ADHERENT_CC_MAIL_FROM');
3093
3094
                            $trackid = 'mem' . $adherent->id;
3095
                            $moreinheader = 'X-Dolibarr-Info: sendReminderForExpiredSubscription' . "\r\n";
3096
3097
                            $cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), $cc, '', 0, 1, '', '', $trackid, $moreinheader);
3098
                            $result = $cmail->sendfile();
3099
                            if (!$result) {
3100
                                $error++;
3101
                                $this->error .= $cmail->error . ' ';
3102
                                if (!is_null($cmail->errors)) {
3103
                                    $this->errors += $cmail->errors;
3104
                                }
3105
                                $nbko++;
3106
                                $listofmembersko[$adherent->id] = $adherent->id;
3107
                            } else {
3108
                                $nbok++;
3109
                                $listofmembersok[$adherent->id] = $adherent->id;
3110
3111
                                $message = $msg;
3112
                                $sendto = $to;
3113
                                $sendtocc = '';
3114
                                $sendtobcc = '';
3115
                                $actioncode = 'EMAIL';
3116
                                $extraparams = '';
3117
3118
                                $actionmsg = '';
3119
                                $actionmsg2 = $langs->transnoentities('MailSentByTo', CMailFile::getValidAddress($from, 4, 0, 1), CMailFile::getValidAddress($sendto, 4, 0, 1));
3120
                                if ($message) {
3121
                                    $actionmsg = $langs->transnoentities('MailFrom') . ': ' . dol_escape_htmltag($from);
3122
                                    $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo') . ': ' . dol_escape_htmltag($sendto));
3123
                                    if ($sendtocc) {
3124
                                        $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . dol_escape_htmltag($sendtocc));
3125
                                    }
3126
                                    $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
3127
                                    $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
3128
                                    $actionmsg = dol_concatdesc($actionmsg, $message);
3129
                                }
3130
3131
                                
3132
                                // Insert record of emails sent
3133
                                $actioncomm = new ActionComm($this->db);
3134
3135
                                $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
3136
                                $actioncomm->code = 'AC_' . $actioncode;
3137
                                $actioncomm->label = $actionmsg2;
3138
                                $actioncomm->note_private = $actionmsg;
3139
                                $actioncomm->fk_project = 0;
3140
                                $actioncomm->datep = $now;
3141
                                $actioncomm->datef = $now;
3142
                                $actioncomm->percentage = -1; // Not applicable
3143
                                $actioncomm->socid = $adherent->thirdparty->id;
3144
                                $actioncomm->contact_id = 0;
3145
                                $actioncomm->authorid = $user->id; // User saving action
3146
                                $actioncomm->userownerid = $user->id; // Owner of action
3147
                                // Fields when action is en email (content should be added into note)
3148
                                $actioncomm->email_msgid = $cmail->msgid;
3149
                                $actioncomm->email_from = $from;
3150
                                $actioncomm->email_sender = '';
3151
                                $actioncomm->email_to = $to;
3152
                                $actioncomm->email_tocc = $sendtocc;
3153
                                $actioncomm->email_tobcc = $sendtobcc;
3154
                                $actioncomm->email_subject = $subject;
3155
                                $actioncomm->errors_to = '';
3156
3157
                                $actioncomm->fk_element = $adherent->id;
3158
                                $actioncomm->elementtype = $adherent->element;
3159
3160
                                $actioncomm->extraparams = $extraparams;
3161
3162
                                $actioncomm->create($user);
3163
                            }
3164
                        } else {
3165
                            //$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
3166
3167
                            $error++;
3168
                            $this->error .= "Can't find email template with label=" . $labeltouse . ", to use for the reminding email ";
3169
3170
                            $nbko++;
3171
                            $listofmembersko[$adherent->id] = $adherent->id;
3172
3173
                            break;
3174
                        }
3175
                    }
3176
3177
                    $i++;
3178
                }
3179
            } else {
3180
                $this->error = $this->db->lasterror();
3181
                return 1;
3182
            }
3183
        }
3184
3185
        if ($blockingerrormsg) {
3186
            $this->error = $blockingerrormsg;
3187
            return 1;
3188
        } else {
3189
            $this->output = 'Found ' . ($nbok + $nbko) . ' members to send reminder to.';
3190
            $this->output .= ' Send email successfully to ' . $nbok . ' members';
3191
            if (is_array($listofmembersok)) {
3192
                $listofids = '';
3193
                $i = 0;
3194
                foreach ($listofmembersok as $idmember) {
3195
                    if ($i > 100) {
3196
                        $listofids .= ', ...';
3197
                        break;
3198
                    }
3199
                    if (empty($listofids)) {
3200
                        $listofids .= ' [';
3201
                    } else {
3202
                        $listofids .= ', ';
3203
                    }
3204
                    $listofids .= $idmember;
3205
                    $i++;
3206
                }
3207
                if ($listofids) {
3208
                    $listofids .= ']';
3209
                }
3210
3211
                $this->output .= ($listofids ? ' ids=' . $listofids : '');
3212
            }
3213
            if ($nbko) {
3214
                $this->output .= ' - Canceled for ' . $nbko . ' member (no email or email sending error)';
3215
                if (is_array($listofmembersko)) {
3216
                    $listofids = '';
3217
                    $i = 0;
3218
                    foreach ($listofmembersko as $idmember) {
3219
                        if ($i > 100) {
3220
                            $listofids .= ', ...';
3221
                            break;
3222
                        }
3223
                        if (empty($listofids)) {
3224
                            $listofids .= ' [';
3225
                        } else {
3226
                            $listofids .= ', ';
3227
                        }
3228
                        $listofids .= $idmember;
3229
                        $i++;
3230
                    }
3231
                    if ($listofids) {
3232
                        $listofids .= ']';
3233
                    }
3234
                    $this->output .= ($listofids ? ' ids=' . $listofids : '');
3235
                }
3236
            }
3237
        }
3238
3239
        return $nbko;
3240
    }
3241
3242
    /**
3243
     *  Return clicable link of object (with eventually picto)
3244
     *
3245
     *  @param      string      $option                 Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
3246
     *  @param      array       $arraydata              Array of data
3247
     *  @return     string                              HTML Code for Kanban thumb.
3248
     */
3249
    public function getKanbanView($option = '', $arraydata = null)
3250
    {
3251
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
3252
3253
        $return = '<div class="box-flex-item box-flex-grow-zero">';
3254
        $return .= '<div class="info-box info-box-sm">';
3255
        $return .= '<span class="info-box-icon bg-infobox-action">';
3256
        if (property_exists($this, 'photo') || !empty($this->photo)) {
3257
            $return .= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photoref photowithmargin photologintooltip', 'small', 0, 1);
3258
        } else {
3259
            $return .= img_picto('', 'user');
3260
        }
3261
        $return .= '</span>';
3262
        $return .= '<div class="info-box-content">';
3263
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref) . '</span>';
3264
        if ($selected >= 0) {
3265
            $return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
3266
        }
3267
        if (property_exists($this, 'type')) {
3268
            $return .= '<br><span class="info-box-label opacitymedium">' . $this->type . '</span>';
3269
        }
3270
        if (method_exists($this, 'getmorphylib')) {
3271
            $return .= '<br><span class="info-box-label">' . $this->getmorphylib('', 2) . '</span>';
3272
        }
3273
        if (method_exists($this, 'getLibStatut')) {
3274
            $return .= '<br><div class="info-box-status paddingtop">';
3275
            $return .= $this->LibStatut($this->status, $this->need_subscription, $this->datefin, 5);
3276
            $return .= '</div>';
3277
        }
3278
        $return .= '</div>';
3279
        $return .= '</div>';
3280
        $return .= '</div>';
3281
        return $return;
3282
    }
3283
}
3284