Passed
Push — main ( f1540e...02d90d )
by Rafael
45:15
created

Adherent::getLibStatut()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

1513
                /** @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...
1514
                $this->status = $obj->statut;
1515
                $this->public = $obj->public;
1516
1517
                $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...
1518
                $this->date_creation = $this->db->jdate($obj->datec);
1519
                $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...
1520
                $this->date_modification = $this->db->jdate($obj->datem);
1521
                $this->datefin = $this->db->jdate($obj->datefin);
1522
                $this->datevalid = $this->db->jdate($obj->datev);
1523
                $this->date_validation = $this->db->jdate($obj->datev);
1524
                $this->birth = $this->db->jdate($obj->birthday);
1525
1526
                $this->default_lang = $obj->default_lang;
1527
1528
                $this->note_private = $obj->note_private;
1529
                $this->note_public = $obj->note_public;
1530
                $this->morphy = $obj->morphy;
1531
1532
                $this->typeid = $obj->fk_adherent_type;
1533
                $this->type = $obj->type;
1534
                $this->need_subscription = $obj->subscription;
1535
1536
                $this->user_id = $obj->user_id;
1537
                $this->user_login = $obj->user_login;
1538
1539
                $this->model_pdf = $obj->model_pdf;
1540
1541
                // Retrieve all extrafield
1542
                // fetch optionals attributes and labels
1543
                if ($fetch_optionals) {
1544
                    $this->fetch_optionals();
1545
                }
1546
1547
                // Load other properties
1548
                if ($fetch_subscriptions) {
1549
                    $result = $this->fetch_subscriptions();
1550
                }
1551
1552
                return $this->id;
1553
            } else {
1554
                return 0;
1555
            }
1556
        } else {
1557
            $this->error = $this->db->lasterror();
1558
            return -1;
1559
        }
1560
    }
1561
1562
1563
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1564
1565
    /**
1566
     *  Function to get member subscriptions data:
1567
     *  subscriptions,
1568
     *  first_subscription_date, first_subscription_date_start, first_subscription_date_end, first_subscription_amount
1569
     *  last_subscription_date, last_subscription_date_start, last_subscription_date_end, last_subscription_amount
1570
     *
1571
     * @return     int         Return integer <0 if KO, >0 if OK
1572
     */
1573
    public function fetch_subscriptions()
1574
    {
1575
        // phpcs:enable
1576
        global $langs;
1577
1578
1579
        $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
1580
        $sql .= " c.tms as datem,";
1581
        $sql .= " c.datec as datec,";
1582
        $sql .= " c.dateadh as dateh,";
1583
        $sql .= " c.datef as datef";
1584
        $sql .= " FROM " . MAIN_DB_PREFIX . "subscription as c";
1585
        $sql .= " WHERE c.fk_adherent = " . ((int) $this->id);
1586
        $sql .= " ORDER BY c.dateadh";
1587
        dol_syslog(get_class($this) . "::fetch_subscriptions", LOG_DEBUG);
1588
1589
        $resql = $this->db->query($sql);
1590
        if ($resql) {
1591
            $this->subscriptions = [];
1592
1593
            $i = 0;
1594
            while ($obj = $this->db->fetch_object($resql)) {
1595
                if ($i == 0) {
1596
                    $this->first_subscription_date = $this->db->jdate($obj->datec);
1597
                    $this->first_subscription_date_start = $this->db->jdate($obj->dateh);
1598
                    $this->first_subscription_date_end = $this->db->jdate($obj->datef);
1599
                    $this->first_subscription_amount = $obj->subscription;
1600
                }
1601
                $this->last_subscription_date = $this->db->jdate($obj->datec);
1602
                $this->last_subscription_date_start = $this->db->jdate($obj->dateh);
1603
                $this->last_subscription_date_end = $this->db->jdate($obj->datef);
1604
                $this->last_subscription_amount = $obj->subscription;
1605
1606
                $subscription = new Subscription($this->db);
1607
                $subscription->id = $obj->rowid;
1608
                $subscription->fk_adherent = $obj->fk_adherent;
1609
                $subscription->fk_type = $obj->fk_type;
1610
                $subscription->amount = $obj->subscription;
1611
                $subscription->note = $obj->note_public;
1612
                $subscription->note_public = $obj->note_public;
1613
                $subscription->fk_bank = $obj->fk_bank;
1614
                $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...
1615
                $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...
1616
                $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...
1617
                $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...
1618
1619
                $this->subscriptions[] = $subscription;
1620
1621
                $i++;
1622
            }
1623
            return 1;
1624
        } else {
1625
            $this->error = $this->db->error() . ' sql=' . $sql;
1626
            return -1;
1627
        }
1628
    }
1629
1630
1631
    /**
1632
     *  Function to get partnerships array
1633
     *
1634
     * @param string $mode 'member' or 'thirdparty'
1635
     *
1636
     * @return     int                     Return integer <0 if KO, >0 if OK
1637
     */
1638
    public function fetchPartnerships($mode)
1639
    {
1640
        global $langs;
1641
1642
        require_once DOL_DOCUMENT_ROOT . '/partnership/class/partnership.class.php';
1643
1644
1645
        $this->partnerships[] = [];
1646
1647
        return 1;
1648
    }
1649
1650
1651
    /**
1652
     *  Insert subscription into database and eventually add links to banks, mailman, etc...
1653
     *
1654
     * @param int    $date            Date of effect of subscription
1655
     * @param double $amount          Amount of subscription (0 accepted for some members)
1656
     * @param int    $accountid       Id bank account. NOT USED.
1657
     * @param string $operation       Code of payment mode (if Id bank account provided). Example: 'CB', ... NOT USED.
1658
     * @param string $label           Label operation (if Id bank account provided).
1659
     * @param string $num_chq         Numero cheque (if Id bank account provided)
1660
     * @param string $emetteur_nom    Name of cheque writer
1661
     * @param string $emetteur_banque Name of bank of cheque
1662
     * @param int    $datesubend      Date end subscription
1663
     * @param int    $fk_type         Member type id
1664
     *
1665
     * @return int                             rowid of record added, <0 if KO
1666
     */
1667
    public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
1668
    {
1669
        global $conf, $langs, $user;
1670
1671
1672
        $error = 0;
1673
1674
        // Clean parameters
1675
        if (!$amount) {
1676
            $amount = 0;
1677
        }
1678
1679
        $this->db->begin();
1680
1681
        if ($datesubend) {
1682
            $datefin = $datesubend;
1683
        } else {
1684
            // If no end date, end date = date + 1 year - 1 day
1685
            $datefin = dol_time_plus_duree($date, 1, 'y');
1686
            $datefin = dol_time_plus_duree($datefin, -1, 'd');
1687
        }
1688
1689
        // Create subscription
1690
        $subscription = new Subscription($this->db);
1691
        $subscription->fk_adherent = $this->id;
1692
        $subscription->dateh = $date; // Date of new subscription
1693
        $subscription->datef = $datefin; // End data of new subscription
1694
        $subscription->amount = $amount;
1695
        $subscription->note = $label; // deprecated
1696
        $subscription->note_public = $label;
1697
        $subscription->fk_type = $fk_type;
1698
1699
        $rowid = $subscription->create($user);
1700
        if ($rowid > 0) {
1701
            // Update denormalized subscription end date (read database subscription to find values)
1702
            // This will also update this->datefin
1703
            $result = $this->update_end_date($user);
1704
            if ($result > 0) {
1705
                // Change properties of object (used by triggers)
1706
                $this->last_subscription_date = dol_now();
1707
                $this->last_subscription_date_start = $date;
1708
                $this->last_subscription_date_end = $datefin;
1709
                $this->last_subscription_amount = $amount;
1710
            }
1711
1712
            if (!$error) {
1713
                $this->db->commit();
1714
                return $rowid;
1715
            } else {
1716
                $this->db->rollback();
1717
                return -2;
1718
            }
1719
        } else {
1720
            $this->setErrorsFromObject($subscription);
1721
            $this->db->rollback();
1722
            return -1;
1723
        }
1724
    }
1725
1726
1727
    /**
1728
     *  Do complementary actions after subscription recording.
1729
     *
1730
     * @param int    $subscriptionid       Id of created subscription
1731
     * @param string $option               Which action ('bankdirect', 'bankviainvoice', 'invoiceonly', ...)
1732
     * @param int    $accountid            Id bank account
1733
     * @param int    $datesubscription     Date of subscription
1734
     * @param int    $paymentdate          Date of payment
1735
     * @param string $operation            Code of type of operation (if Id bank account provided). Example 'CB', ...
1736
     * @param string $label                Label operation (if Id bank account provided)
1737
     * @param double $amount               Amount of subscription (0 accepted for some members)
1738
     * @param string $num_chq              Numero cheque (if Id bank account provided)
1739
     * @param string $emetteur_nom         Name of cheque writer
1740
     * @param string $emetteur_banque      Name of bank of cheque
1741
     * @param int    $autocreatethirdparty Auto create new thirdparty if member not yet linked to a thirdparty and we
1742
     *                                     request an option that generate invoice.
1743
     * @param string $ext_payment_id       External id of payment (for example Stripe charge id)
1744
     * @param string $ext_payment_site     Name of external paymentmode (for example 'stripe')
1745
     *
1746
     * @return int                                 Return integer <0 if KO, >0 if OK
1747
     */
1748
    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 = '')
1749
    {
1750
        global $conf, $langs, $user, $mysoc;
1751
1752
        $error = 0;
1753
1754
        $this->invoice = null; // This will contains invoice if an invoice is created
1755
1756
        dol_syslog("subscriptionComplementaryActions subscriptionid=" . $subscriptionid . " option=" . $option . " accountid=" . $accountid . " datesubscription=" . $datesubscription . " paymentdate=" .
1757
            $paymentdate . " label=" . $label . " amount=" . $amount . " num_chq=" . $num_chq . " autocreatethirdparty=" . $autocreatethirdparty);
1758
1759
        // Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
1760
        if ($option == 'bankdirect' && $accountid) {
1761
            $acct = new Account($this->db);
1762
            $result = $acct->fetch($accountid);
1763
1764
            $dateop = $paymentdate;
1765
1766
            $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, '', $user, $emetteur_nom, $emetteur_banque);
1767
            if ($insertid > 0) {
1768
                $inserturlid = $acct->add_url_line($insertid, $this->id, DOL_URL_ROOT . '/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
1769
                if ($inserturlid > 0) {
1770
                    // Update table subscription
1771
                    $sql = "UPDATE " . MAIN_DB_PREFIX . "subscription SET fk_bank=" . ((int) $insertid);
1772
                    $sql .= " WHERE rowid=" . ((int) $subscriptionid);
1773
1774
                    dol_syslog("subscription::subscription", LOG_DEBUG);
1775
                    $resql = $this->db->query($sql);
1776
                    if (!$resql) {
1777
                        $error++;
1778
                        $this->error = $this->db->lasterror();
1779
                        $this->errors[] = $this->error;
1780
                    }
1781
                } else {
1782
                    $error++;
1783
                    $this->setErrorsFromObject($acct);
1784
                }
1785
            } else {
1786
                $error++;
1787
                $this->setErrorsFromObject($acct);
1788
            }
1789
        }
1790
1791
        // If option chosen, we create invoice
1792
        if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
1793
            require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/paymentterm.class.php';
1794
1795
            $invoice = new Facture($this->db);
1796
            $customer = new Societe($this->db);
1797
1798
            if (!$error) {
1799
                if (!($this->fk_soc > 0)) { // If not yet linked to a company
1800
                    if ($autocreatethirdparty) {
1801
                        // Create a linked thirdparty to member
1802
                        $companyalias = '';
1803
                        $fullname = $this->getFullName($langs);
1804
1805
                        if ($this->morphy == 'mor') {
1806
                            $companyname = $this->company;
1807
                            if (!empty($fullname)) {
1808
                                $companyalias = $fullname;
1809
                            }
1810
                        } else {
1811
                            $companyname = $fullname;
1812
                            if (!empty($this->company)) {
1813
                                $companyalias = $this->company;
1814
                            }
1815
                        }
1816
1817
                        $result = $customer->create_from_member($this, $companyname, $companyalias);
1818
                        if ($result < 0) {
1819
                            $this->error = $customer->error;
1820
                            $this->errors = $customer->errors;
1821
                            $error++;
1822
                        } else {
1823
                            $this->fk_soc = $result;
1824
                        }
1825
                    } else {
1826
                        $langs->load("errors");
1827
                        $this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1828
                        $this->errors[] = $this->error;
1829
                        $error++;
1830
                    }
1831
                }
1832
            }
1833
            if (!$error) {
1834
                $result = $customer->fetch($this->fk_soc);
1835
                if ($result <= 0) {
1836
                    $this->error = $customer->error;
1837
                    $this->errors = $customer->errors;
1838
                    $error++;
1839
                }
1840
            }
1841
1842
            if (!$error) {
1843
                // Create draft invoice
1844
                $invoice->type = Facture::TYPE_STANDARD;
1845
                $invoice->cond_reglement_id = $customer->cond_reglement_id;
1846
                if (empty($invoice->cond_reglement_id)) {
1847
                    $paymenttermstatic = new PaymentTerm($this->db);
1848
                    $invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
1849
                    if (empty($invoice->cond_reglement_id)) {
1850
                        $error++;
1851
                        $this->error = 'ErrorNoPaymentTermRECEPFound';
1852
                        $this->errors[] = $this->error;
1853
                    }
1854
                }
1855
                $invoice->socid = $this->fk_soc;
1856
                //$invoice->date = $datesubscription;
1857
                $invoice->date = dol_now();
1858
1859
                // Possibility to add external linked objects with hooks
1860
                $invoice->linked_objects['subscription'] = $subscriptionid;
1861
                if (!empty($_POST['other_linked_objects']) && is_array($_POST['other_linked_objects'])) {
1862
                    $invoice->linked_objects = array_merge($invoice->linked_objects, $_POST['other_linked_objects']);
1863
                }
1864
1865
                $result = $invoice->create($user);
1866
                if ($result <= 0) {
1867
                    $this->error = $invoice->error;
1868
                    $this->errors = $invoice->errors;
1869
                    $error++;
1870
                } else {
1871
                    $this->invoice = $invoice;
1872
                }
1873
            }
1874
1875
            if (!$error) {
1876
                // Add line to draft invoice
1877
                $idprodsubscription = 0;
1878
                if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
1879
                    $idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
1880
                }
1881
1882
                $vattouse = 0;
1883
                if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
1884
                    $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
1885
                }
1886
                //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1887
                // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1888
                $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, '', 'TTC', $amount, 1);
1889
                if ($result <= 0) {
1890
                    $this->error = $invoice->error;
1891
                    $this->errors = $invoice->errors;
1892
                    $error++;
1893
                }
1894
            }
1895
1896
            if (!$error) {
1897
                // Validate invoice
1898
                $result = $invoice->validate($user);
1899
                if ($result <= 0) {
1900
                    $this->error = $invoice->error;
1901
                    $this->errors = $invoice->errors;
1902
                    $error++;
1903
                }
1904
            }
1905
1906
            if (!$error) {
1907
                // TODO Link invoice with subscription ?
1908
            }
1909
1910
            // Add payment onto invoice
1911
            if (!$error && $option == 'bankviainvoice' && $accountid) {
1912
                require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
1913
                require_once BASE_PATH . '/../Dolibarr/Lib/Files.php';
1914
1915
                $amounts = [];
1916
                $amounts[$invoice->id] = (float) price2num($amount);
1917
1918
                $paiement = new Paiement($this->db);
0 ignored issues
show
Bug introduced by
The type DoliModules\Adherent\Model\Paiement was not found. Did you mean Paiement? If so, make sure to prefix the type with \.
Loading history...
1919
                $paiement->datepaye = $paymentdate;
1920
                $paiement->amounts = $amounts;
1921
                $paiement->paiementcode = $operation;
1922
                $paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
1923
                $paiement->num_payment = $num_chq;
1924
                $paiement->note_public = $label;
1925
                $paiement->ext_payment_id = $ext_payment_id;
1926
                $paiement->ext_payment_site = $ext_payment_site;
1927
1928
                if (!$error) {
1929
                    // Create payment line for invoice
1930
                    $paiement_id = $paiement->create($user);
1931
                    if (!($paiement_id > 0)) {
1932
                        $this->error = $paiement->error;
1933
                        $this->errors = $paiement->errors;
1934
                        $error++;
1935
                    }
1936
                }
1937
1938
                if (!$error) {
1939
                    // Add transaction into bank account
1940
                    $bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
1941
                    if (!($bank_line_id > 0)) {
1942
                        $this->error = $paiement->error;
1943
                        $this->errors = $paiement->errors;
1944
                        $error++;
1945
                    }
1946
                }
1947
1948
                if (!$error && !empty($bank_line_id)) {
1949
                    // Update fk_bank into subscription table
1950
                    $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'subscription SET fk_bank=' . ((int) $bank_line_id);
1951
                    $sql .= ' WHERE rowid=' . ((int) $subscriptionid);
1952
1953
                    $result = $this->db->query($sql);
1954
                    if (!$result) {
1955
                        $error++;
1956
                    }
1957
                }
1958
1959
                if (!$error) {
1960
                    // Set invoice as paid
1961
                    $invoice->setPaid($user);
1962
                }
1963
            }
1964
1965
            if (!$error) {
1966
                // Define output language
1967
                $outputlangs = $langs;
1968
                $newlang = '';
1969
                $lang_id = GETPOST('lang_id');
1970
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
1971
                    $newlang = $lang_id;
1972
                }
1973
                if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1974
                    $newlang = $customer->default_lang;
1975
                }
1976
                if (!empty($newlang)) {
1977
                    $outputlangs = new Translate("", $conf);
0 ignored issues
show
Bug introduced by
The type DoliModules\Adherent\Model\Translate was not found. Did you mean Translate? If so, make sure to prefix the type with \.
Loading history...
1978
                    $outputlangs->setDefaultLang($newlang);
1979
                }
1980
                // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
1981
                //if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
1982
1983
                $invoice->generateDocument($invoice->model_pdf, $outputlangs);
1984
            }
1985
        }
1986
1987
        if ($error) {
1988
            return -1;
1989
        } else {
1990
            return 1;
1991
        }
1992
    }
1993
1994
1995
    /**
1996
     *      Function that validate a member
1997
     *
1998
     * @param User $user user adherent qui valide
1999
     *
2000
     * @return int                 Return integer <0 if KO, 0 if nothing done, >0 if OK
2001
     */
2002
    public function validate($user)
2003
    {
2004
        global $langs, $conf;
2005
2006
        $error = 0;
2007
        $now = dol_now();
2008
2009
        // Check parameters
2010
        if ($this->statut == self::STATUS_VALIDATED) {
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2010
        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...
2011
            dol_syslog(get_class($this) . "::validate statut of member does not allow this", LOG_WARNING);
2012
            return 0;
2013
        }
2014
2015
        $this->db->begin();
2016
2017
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2018
        $sql .= " statut = " . self::STATUS_VALIDATED;
2019
        $sql .= ", datevalid = '" . $this->db->idate($now) . "'";
2020
        $sql .= ", fk_user_valid = " . ((int) $user->id);
2021
        $sql .= " WHERE rowid = " . ((int) $this->id);
2022
2023
        dol_syslog(get_class($this) . "::validate", LOG_DEBUG);
2024
        $result = $this->db->query($sql);
2025
        if ($result) {
2026
            $this->statut = self::STATUS_VALIDATED;
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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
            /** @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...
2027
2028
            // Call trigger
2029
            $result = $this->call_trigger('MEMBER_VALIDATE', $user);
2030
            if ($result < 0) {
2031
                $error++;
2032
                $this->db->rollback();
2033
                return -1;
2034
            }
2035
            // End call triggers
2036
2037
            $this->datevalid = $now;
2038
2039
            $this->db->commit();
2040
            return 1;
2041
        } else {
2042
            $this->error = $this->db->error();
2043
            $this->db->rollback();
2044
            return -1;
2045
        }
2046
    }
2047
2048
2049
    /**
2050
     *      Fonction qui resilie un adherent
2051
     *
2052
     * @param User $user User making change
2053
     *
2054
     * @return int                 Return integer <0 if KO, >0 if OK
2055
     */
2056
    public function resiliate($user)
2057
    {
2058
        global $langs, $conf;
2059
2060
        $error = 0;
2061
2062
        // Check parameters
2063
        if ($this->statut == self::STATUS_RESILIATED) {
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2063
        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...
2064
            dol_syslog(get_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2065
            return 0;
2066
        }
2067
2068
        $this->db->begin();
2069
2070
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2071
        $sql .= " statut = " . self::STATUS_RESILIATED;
2072
        $sql .= ", fk_user_valid=" . $user->id;
2073
        $sql .= " WHERE rowid = " . ((int) $this->id);
2074
2075
        $result = $this->db->query($sql);
2076
        if ($result) {
2077
            $this->statut = self::STATUS_RESILIATED;
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2077
            /** @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...
2078
2079
            // Call trigger
2080
            $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2081
            if ($result < 0) {
2082
                $error++;
2083
                $this->db->rollback();
2084
                return -1;
2085
            }
2086
            // End call triggers
2087
2088
            $this->db->commit();
2089
            return 1;
2090
        } else {
2091
            $this->error = $this->db->error();
2092
            $this->db->rollback();
2093
            return -1;
2094
        }
2095
    }
2096
2097
    /**
2098
     *      Functiun to exclude (set adherent.status to -2) a member
2099
     *      TODO
2100
     *      A private note should be added to know why the member has been excluded
2101
     *      For historical purpose it add an "extra-subscription" type excluded
2102
     *
2103
     * @param User $user User making change
2104
     *
2105
     * @return int                 Return integer <0 if KO, >0 if OK
2106
     */
2107
    public function exclude($user)
2108
    {
2109
        $error = 0;
2110
2111
        // Check parameters
2112
        if ($this->statut == self::STATUS_EXCLUDED) {
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2112
        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...
2113
            dol_syslog(get_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2114
            return 0;
2115
        }
2116
2117
        $this->db->begin();
2118
2119
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2120
        $sql .= " statut = " . self::STATUS_EXCLUDED;
2121
        $sql .= ", fk_user_valid=" . $user->id;
2122
        $sql .= " WHERE rowid = " . ((int) $this->id);
2123
2124
        $result = $this->db->query($sql);
2125
        if ($result) {
2126
            $this->statut = self::STATUS_EXCLUDED;
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

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

2426
                $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...
2427
                    ($morecss ? ' usertext' . $morecss : '') . '">';
2428
            }
2429
            if ($mode == 'login') {
2430
                $result .= dol_trunc($this->login, $maxlen);
2431
            } elseif ($mode == 'ref') {
2432
                $result .= $this->ref;
2433
            } else {
2434
                $result .= $this->getFullName($langs, '', ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2435
            }
2436
            if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2437
                $result .= '</span>';
2438
            }
2439
        }
2440
        if ($withpictoimg) {
2441
            $result .= '</div>';
2442
        }
2443
        $result .= $linkend;
2444
2445
        if ($addlinktonotes) {
2446
            if ($this->note_private) {
2447
                $notetoshow = $langs->trans("ViewPrivateNote") . ':<br>' . dol_string_nohtmltag($this->note_private, 1);
2448
                $result .= ' <span class="note inline-block">';
2449
                $result .= '<a href="' . DOL_URL_ROOT . '/adherents/note.php?id=' . $this->id . '" class="classfortooltip" title="' . dol_escape_htmltag($notetoshow) . '">';
2450
                $result .= img_picto('', 'note');
2451
                $result .= '</a>';
2452
                $result .= '</span>';
2453
            }
2454
        }
2455
        global $action;
2456
        $hookmanager->initHooks([$this->element . 'dao']);
2457
        $parameters = ['id' => $this->id, 'getnomurl' => &$result];
2458
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2459
        if ($reshook > 0) {
2460
            $result = $hookmanager->resPrint;
2461
        } else {
2462
            $result .= $hookmanager->resPrint;
2463
        }
2464
        return $result;
2465
    }
2466
2467
    /**
2468
     *  Retourne le libelle du statut d'un adherent (brouillon, valide, resilie, exclu)
2469
     *
2470
     * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long,
2471
     *                  5=Libelle court + Picto
2472
     *
2473
     * @return string              Label
2474
     */
2475
    public function getLibStatut($mode = 0)
2476
    {
2477
        return $this->LibStatut($this->statut, $this->need_subscription, $this->datefin, $mode);
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2477
        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...
2478
    }
2479
2480
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2481
2482
    /**
2483
     *  Renvoi le libelle d'un statut donne
2484
     *
2485
     * @param int $status                Id status
2486
     * @param int $need_subscription     1 if member type need subscription, 0 otherwise
2487
     * @param int $date_end_subscription Date fin adhesion
2488
     * @param int $mode                  0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long
2489
     *                                   label, 5=Short label + Picto, 6=Long label + Picto
2490
     *
2491
     * @return string                              Label
2492
     */
2493
    public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
2494
    {
2495
        // phpcs:enable
2496
        global $langs;
2497
        $langs->load("members");
2498
2499
        $statusType = '';
2500
        $labelStatus = '';
2501
        $labelStatusShort = '';
2502
2503
        if ($status == self::STATUS_DRAFT) {
2504
            $statusType = 'status0';
2505
            $labelStatus = $langs->trans("MemberStatusDraft");
2506
            $labelStatusShort = $langs->trans("MemberStatusDraftShort");
2507
        } elseif ($status >= self::STATUS_VALIDATED) {
2508
            if ($need_subscription === 0) {
2509
                $statusType = 'status4';
2510
                $labelStatus = $langs->trans("MemberStatusNoSubscription");
2511
                $labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
2512
            } elseif (!$date_end_subscription) {
2513
                $statusType = 'status1';
2514
                $labelStatus = $langs->trans("WaitingSubscription");
2515
                $labelStatusShort = $langs->trans("WaitingSubscriptionShort");
2516
            } elseif ($date_end_subscription < dol_now()) { // expired
2517
                $statusType = 'status8';
2518
                $labelStatus = $langs->trans("MemberStatusActiveLate");
2519
                $labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
2520
            } else {
2521
                $statusType = 'status4';
2522
                $labelStatus = $langs->trans("MemberStatusPaid");
2523
                $labelStatusShort = $langs->trans("MemberStatusPaidShort");
2524
            }
2525
        } elseif ($status == self::STATUS_RESILIATED) {
2526
            $statusType = 'status6';
2527
            $labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
2528
            $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
2529
        } elseif ($status == self::STATUS_EXCLUDED) {
2530
            $statusType = 'status10';
2531
            $labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
2532
            $labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
2533
        }
2534
2535
        return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
2536
    }
2537
2538
2539
    /**
2540
     *      Load indicators this->nb in state board
2541
     *
2542
     * @return     int         Return integer <0 if KO, >0 if OK
2543
     */
2544
    public function loadStateBoard()
2545
    {
2546
        global $conf;
2547
2548
        $this->nb = [];
2549
2550
        $sql = "SELECT count(a.rowid) as nb";
2551
        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent as a";
2552
        $sql .= " WHERE a.statut > 0";
2553
        $sql .= " AND a.entity IN (" . getEntity('adherent') . ")";
2554
2555
        $resql = $this->db->query($sql);
2556
        if ($resql) {
2557
            while ($obj = $this->db->fetch_object($resql)) {
2558
                $this->nb["members"] = $obj->nb;
2559
            }
2560
            $this->db->free($resql);
2561
            return 1;
2562
        } else {
2563
            dol_print_error($this->db);
2564
            $this->error = $this->db->error();
2565
            return -1;
2566
        }
2567
    }
2568
2569
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2570
2571
    /**
2572
     *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
2573
     *
2574
     * @param User   $user Object user
2575
     * @param string $mode "expired" for membership to renew, "shift" for member to validate
2576
     *
2577
     * @return WorkboardResponse|int   Return integer <0 if KO, WorkboardResponse if OK
2578
     */
2579
    public function load_board($user, $mode)
2580
    {
2581
        // phpcs:enable
2582
        global $conf, $langs;
2583
2584
        if ($user->socid) {
2585
            return -1; // protection pour eviter appel par utilisateur externe
2586
        }
2587
2588
        $now = dol_now();
2589
2590
        $sql = "SELECT a.rowid, a.datefin, a.statut";
2591
        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent as a";
2592
        $sql .= ", " . MAIN_DB_PREFIX . "adherent_type as t";
2593
        $sql .= " WHERE a.fk_adherent_type = t.rowid";
2594
        if ($mode == 'expired') {
2595
            $sql .= " AND a.statut = " . self::STATUS_VALIDATED;
2596
            $sql .= " AND a.entity IN (" . getEntity('adherent') . ")";
2597
            $sql .= " AND ((a.datefin IS NULL or a.datefin < '" . $this->db->idate($now) . "') AND t.subscription = '1')";
2598
        } elseif ($mode == 'shift') {
2599
            $sql .= " AND a.statut = " . self::STATUS_DRAFT;
2600
            $sql .= " AND a.entity IN (" . getEntity('adherent') . ")";
2601
        }
2602
2603
        $resql = $this->db->query($sql);
2604
        if ($resql) {
2605
            $langs->load("members");
2606
2607
            $warning_delay = 0;
2608
            $url = '';
2609
            $label = '';
2610
            $labelShort = '';
2611
2612
            if ($mode == 'expired') {
2613
                $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2614
                $label = $langs->trans("MembersWithSubscriptionToReceive");
2615
                $labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
2616
                $url = DOL_URL_ROOT . '/adherents/list.php?mainmenu=members&amp;statut=' . self::STATUS_VALIDATED . '&amp;filter=outofdate';
2617
            } elseif ($mode == 'shift') {
2618
                $warning_delay = $conf->adherent->subscription->warning_delay / 60 / 60 / 24;
2619
                $url = DOL_URL_ROOT . '/adherents/list.php?mainmenu=members&amp;statut=' . self::STATUS_DRAFT;
2620
                $label = $langs->trans("MembersListToValid");
2621
                $labelShort = $langs->trans("ToValidate");
2622
            }
2623
2624
            $response = new WorkboardResponse();
2625
            $response->warning_delay = $warning_delay;
2626
            $response->label = $label;
2627
            $response->labelShort = $labelShort;
2628
            $response->url = $url;
2629
            $response->img = img_object('', "user");
2630
2631
            $adherentstatic = new Adherent($this->db);
2632
2633
            while ($obj = $this->db->fetch_object($resql)) {
2634
                $response->nbtodo++;
2635
2636
                $adherentstatic->datefin = $this->db->jdate($obj->datefin);
2637
                $adherentstatic->statut = $obj->statut;
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2637
                /** @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...
2638
2639
                if ($adherentstatic->hasDelay()) {
2640
                    $response->nbtodolate++;
2641
                }
2642
            }
2643
2644
            return $response;
2645
        } else {
2646
            dol_print_error($this->db);
2647
            $this->error = $this->db->error();
2648
            return -1;
2649
        }
2650
    }
2651
2652
2653
    /**
2654
     *  Create a document onto disk according to template module.
2655
     *
2656
     * @param string     $modele      Force template to use ('' to not force)
2657
     * @param Translate  $outputlangs object lang a utiliser pour traduction
2658
     * @param int        $hidedetails Hide details of lines
2659
     * @param int        $hidedesc    Hide description
2660
     * @param int        $hideref     Hide ref
2661
     * @param null|array $moreparams  Array to provide more information
2662
     *
2663
     * @return     int                         0 if KO, 1 if OK
2664
     */
2665
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2666
    {
2667
        global $conf, $langs;
2668
2669
        $langs->load("orders");
2670
2671
        if (!dol_strlen($modele)) {
2672
            $modele = 'standard';
2673
2674
            if ($this->model_pdf) {
2675
                $modele = $this->model_pdf;
2676
            } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2677
                $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2678
            }
2679
        }
2680
2681
        $modelpath = "core/modules/member/doc/";
2682
2683
        return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2684
    }
2685
2686
2687
    /**
2688
     *  Initialise an instance with random values.
2689
     *  Used to build previews or test instances.
2690
     *  id must be 0 if object instance is a specimen.
2691
     *
2692
     * @return int
2693
     */
2694
    public function initAsSpecimen()
2695
    {
2696
        global $user, $langs;
2697
        $now = dol_now();
2698
2699
        // Initialise parameters
2700
        $this->id = 0;
2701
        $this->ref = 'ABC001';
2702
        $this->entity = 1;
2703
        $this->specimen = 1;
2704
        $this->civility_id = 'MR';
2705
        $this->lastname = 'DOLIBARR';
2706
        $this->firstname = 'SPECIMEN';
2707
        $this->gender = 'man';
2708
        $this->login = 'dolibspec';
2709
        $this->pass = 'dolibspec';
2710
        $this->company = 'Societe ABC';
2711
        $this->address = '61 jump street';
2712
        $this->zip = '75000';
2713
        $this->town = 'Paris';
2714
        $this->country_id = 1;
2715
        $this->country_code = 'FR';
2716
        $this->country = 'France';
2717
        $this->morphy = 'mor';
2718
        $this->email = '[email protected]';
2719
        $this->socialnetworks = [
2720
            'skype' => 'skypepseudo',
2721
            'twitter' => 'twitterpseudo',
2722
            'facebook' => 'facebookpseudo',
2723
            'linkedin' => 'linkedinpseudo',
2724
        ];
2725
        $this->phone = '0999999999';
2726
        $this->phone_perso = '0999999998';
2727
        $this->phone_mobile = '0999999997';
2728
        $this->note_public = 'This is a public note';
2729
        $this->note_private = 'This is a private note';
2730
        $this->birth = $now;
2731
        $this->photo = '';
2732
        $this->public = 1;
2733
        $this->statut = self::STATUS_DRAFT;
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2733
        /** @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...
2734
2735
        $this->datefin = $now;
2736
        $this->datevalid = $now;
2737
        $this->default_lang = '';
2738
2739
        $this->typeid = 1; // Id type adherent
2740
        $this->type = 'Type adherent'; // Libelle type adherent
2741
        $this->need_subscription = 0;
2742
2743
        $this->first_subscription_date = $now;
2744
        $this->first_subscription_date_start = $this->first_subscription_date;
2745
        $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2746
        $this->first_subscription_amount = 10;
2747
2748
        $this->last_subscription_date = $this->first_subscription_date;
2749
        $this->last_subscription_date_start = $this->first_subscription_date;
2750
        $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2751
        $this->last_subscription_amount = 10;
2752
        return 1;
2753
    }
2754
2755
2756
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2757
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2758
    /**
2759
     *  Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
2760
     *
2761
     * @param array $info           Info array loaded by _load_ldap_info
2762
     * @param int   $mode           0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
2763
     *                              1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
2764
     *                              2=Return key only (uid=qqq)
2765
     *
2766
     * @return string              DN
2767
     */
2768
    public function _load_ldap_dn($info, $mode = 0)
2769
    {
2770
        // phpcs:enable
2771
        global $conf;
2772
        $dn = '';
2773
        if ($mode == 0) {
2774
            $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=" . $info[getDolGlobalString('LDAP_KEY_MEMBERS')] . "," . getDolGlobalString('LDAP_MEMBER_DN');
2775
        }
2776
        if ($mode == 1) {
2777
            $dn = getDolGlobalString('LDAP_MEMBER_DN');
2778
        }
2779
        if ($mode == 2) {
2780
            $dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=" . $info[getDolGlobalString('LDAP_KEY_MEMBERS')];
2781
        }
2782
        return $dn;
2783
    }
2784
2785
2786
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2787
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2788
    /**
2789
     *  Initialise tableau info (tableau des attributes LDAP)
2790
     *
2791
     * @return     array       Tableau info des attributes
2792
     */
2793
    public function _load_ldap_info()
2794
    {
2795
        // phpcs:enable
2796
        global $conf, $langs;
2797
2798
        $info = [];
2799
        $socialnetworks = getArrayOfSocialNetworks();
2800
        $keymodified = false;
2801
2802
        // Object classes
2803
        $info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
2804
2805
        $this->fullname = $this->getFullName($langs);
2806
2807
        // For avoid ldap error when firstname and lastname are empty
2808
        if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
2809
            $this->fullname = $this->company;
2810
            $this->lastname = $this->company;
2811
        }
2812
2813
        // Possible LDAP KEY (constname => varname)
2814
        $ldapkey = [
2815
            'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
2816
            'LDAP_MEMBER_FIELD_NAME' => 'lastname',
2817
            'LDAP_MEMBER_FIELD_LOGIN' => 'login',
2818
            'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
2819
            'LDAP_MEMBER_FIELD_MAIL' => 'email',
2820
        ];
2821
2822
        // Member
2823
        foreach ($ldapkey as $constname => $varname) {
2824
            if (!empty($this->$varname) && getDolGlobalString($constname)) {
2825
                $info[getDolGlobalString($constname)] = $this->$varname;
2826
2827
                // Check if it is the LDAP key and if its value has been changed
2828
                if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
2829
                    if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
2830
                        $keymodified = true; // For check if LDAP key has been modified
2831
                    }
2832
                }
2833
            }
2834
        }
2835
        if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
2836
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
2837
        }
2838
        if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
2839
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
2840
        }
2841
        if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
2842
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
2843
        }
2844
        if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
2845
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
2846
        }
2847
        if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
2848
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
2849
        }
2850
        if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
2851
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
2852
        }
2853
        if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
2854
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
2855
        }
2856
        foreach ($socialnetworks as $key => $value) {
2857
            if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_' . strtoupper($value['label']))) {
2858
                $info[getDolGlobalString('LDAP_MEMBER_FIELD_' . strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
2859
            }
2860
        }
2861
        if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
2862
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
2863
        }
2864
        if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
2865
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
2866
        }
2867
        if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
2868
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
2869
        }
2870
        if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
2871
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
2872
        }
2873
        if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
2874
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
2875
        }
2876
        if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
2877
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
2878
        }
2879
        if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
2880
            $info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
2881
        }
2882
        if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

2882
        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...
2883
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
2884
        }
2885
        if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
2886
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
2887
        }
2888
2889
        // When password is modified
2890
        if (!empty($this->pass)) {
2891
            if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2892
                $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
2893
            }
2894
            if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2895
                $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2896
            }
2897
        } elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
2898
            // Set LDAP password if possible
2899
            // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2900
            if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
2901
                // Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
2902
                if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
2903
                    if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2904
                        // Create OpenLDAP MD5 password from Dolibarr MD5 password
2905
                        // Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
2906
                        $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
2907
                    }
2908
                }
2909
            } elseif (!empty($this->pass_indatabase)) {
2910
                // Use $this->pass_indatabase value if exists
2911
                if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
2912
                    $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
2913
                }
2914
                if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
2915
                    $info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
2916
                }
2917
            }
2918
        }
2919
2920
        // Subscriptions
2921
        if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
2922
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
2923
        }
2924
        if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
2925
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
2926
        }
2927
        if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
2928
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
2929
        }
2930
        if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
2931
            $info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
2932
        }
2933
2934
        return $info;
2935
    }
2936
2937
2938
    /**
2939
     *      Load type info information in the member object
2940
     *
2941
     * @param int $id Id of member to load
2942
     *
2943
     * @return void
2944
     */
2945
    public function info($id)
2946
    {
2947
        $sql = 'SELECT a.rowid, a.datec as datec,';
2948
        $sql .= ' a.datevalid as datev,';
2949
        $sql .= ' a.tms as datem,';
2950
        $sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2951
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'adherent as a';
2952
        $sql .= ' WHERE a.rowid = ' . ((int) $id);
2953
2954
        dol_syslog(get_class($this) . "::info", LOG_DEBUG);
2955
        $result = $this->db->query($sql);
2956
        if ($result) {
2957
            if ($this->db->num_rows($result)) {
2958
                $obj = $this->db->fetch_object($result);
2959
2960
                $this->id = $obj->rowid;
2961
2962
                $this->user_creation_id = $obj->fk_user_author;
2963
                $this->user_validation_id = $obj->fk_user_valid;
2964
                $this->user_modification_id = $obj->fk_user_mod;
2965
                $this->date_creation = $this->db->jdate($obj->datec);
2966
                $this->date_validation = $this->db->jdate($obj->datev);
2967
                $this->date_modification = $this->db->jdate($obj->datem);
2968
            }
2969
2970
            $this->db->free($result);
2971
        } else {
2972
            dol_print_error($this->db);
2973
        }
2974
    }
2975
2976
    /**
2977
     *  Return number of mass Emailing received by this member with its email
2978
     *
2979
     * @return       int     Number of EMailings
2980
     */
2981
    public function getNbOfEMailings()
2982
    {
2983
        $sql = "SELECT count(mc.email) as nb";
2984
        $sql .= " FROM " . MAIN_DB_PREFIX . "mailing_cibles as mc";
2985
        $sql .= " WHERE mc.email = '" . $this->db->escape($this->email) . "'";
2986
        $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec success
2987
2988
        $resql = $this->db->query($sql);
2989
        if ($resql) {
2990
            $obj = $this->db->fetch_object($resql);
2991
            $nb = $obj->nb;
2992
2993
            $this->db->free($resql);
2994
            return $nb;
2995
        } else {
2996
            $this->error = $this->db->error();
2997
            return -1;
2998
        }
2999
    }
3000
3001
    /**
3002
     * Sets object to supplied categories.
3003
     *
3004
     * Deletes object from existing categories not supplied.
3005
     * Adds it to non existing supplied categories.
3006
     * Existing categories are left untouch.
3007
     *
3008
     * @param int[]|int $categories Category or categories IDs
3009
     *
3010
     * @return  int                         Return integer <0 if KO, >0 if OK
3011
     */
3012
    public function setCategories($categories)
3013
    {
3014
        return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
3015
    }
3016
3017
    /**
3018
     * Function used to replace a thirdparty id with another one.
3019
     *
3020
     * @param DoliDB $db        Database handler
3021
     * @param int    $origin_id Old thirdparty id
3022
     * @param int    $dest_id   New thirdparty id
3023
     *
3024
     * @return bool
3025
     */
3026
    public static function replaceThirdparty($db, $origin_id, $dest_id)
3027
    {
3028
        $tables = ['adherent'];
3029
3030
        return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
3031
    }
3032
3033
    /**
3034
     * Return if a member is late (subscription late) or not
3035
     *
3036
     * @return boolean     True if late, False if not late
3037
     */
3038
    public function hasDelay()
3039
    {
3040
        global $conf;
3041
3042
        //Only valid members
3043
        if ($this->statut != self::STATUS_VALIDATED) {
0 ignored issues
show
Deprecated Code introduced by
The property DoliCore\Base\GenericDocument::$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

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