Test Failed
Branch main (fda838)
by Rafael
50:22
created

Adherent::_load_ldap_info()   F

Complexity

Conditions 66
Paths > 20000

Size

Total Lines 142
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 66
eloc 80
nc 408944640
nop 0
dl 0
loc 142
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
45
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
46
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
47
require_once DOL_DOCUMENT_ROOT . '/core/class/commonpeople.class.php';
48
49
use Account;
50
use ActionComm;
51
use Categorie;
52
use CMailFile;
53
use CommonObject;
54
use CommonPeople;
55
use DoliCore\Base\GenericDocument;
56
use DoliDB;
57
use Facture;
58
use Form;
59
use FormMail;
60
use MailmanSpip;
61
use Paiement;
62
use PaymentTerm;
63
use Societe;
64
use Translate;
65
use User;
66
use WorkboardResponse;
67
68
/**
69
 *      Class to manage members of a foundation
70
 */
71
class Adherent extends GenericDocument
0 ignored issues
show
Deprecated Code introduced by
The class DoliCore\Base\GenericDocument has been deprecated: This class is only needed for compatibility with Dolibarr. ( Ignorable by Annotation )

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

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

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

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

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

2038
        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...
2039
            dol_syslog(get_class($this) . "::validate statut of member does not allow this", LOG_WARNING);
2040
            return 0;
2041
        }
2042
2043
        $this->db->begin();
2044
2045
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2046
        $sql .= " statut = " . self::STATUS_VALIDATED;
2047
        $sql .= ", datevalid = '" . $this->db->idate($now) . "'";
2048
        $sql .= ", fk_user_valid = " . ((int) $user->id);
2049
        $sql .= " WHERE rowid = " . ((int) $this->id);
2050
2051
        dol_syslog(get_class($this) . "::validate", LOG_DEBUG);
2052
        $result = $this->db->query($sql);
2053
        if ($result) {
2054
            $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

2054
            /** @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...
2055
2056
            // Call trigger
2057
            $result = $this->call_trigger('MEMBER_VALIDATE', $user);
2058
            if ($result < 0) {
2059
                $error++;
2060
                $this->db->rollback();
2061
                return -1;
2062
            }
2063
            // End call triggers
2064
2065
            $this->datevalid = $now;
2066
2067
            $this->db->commit();
2068
            return 1;
2069
        } else {
2070
            $this->error = $this->db->error();
2071
            $this->db->rollback();
2072
            return -1;
2073
        }
2074
    }
2075
2076
2077
    /**
2078
     *      Fonction qui resilie un adherent
2079
     *
2080
     * @param User $user User making change
2081
     *
2082
     * @return int                 Return integer <0 if KO, >0 if OK
2083
     */
2084
    public function resiliate($user)
2085
    {
2086
        global $langs, $conf;
2087
2088
        $error = 0;
2089
2090
        // Check parameters
2091
        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

2091
        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...
2092
            dol_syslog(get_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2093
            return 0;
2094
        }
2095
2096
        $this->db->begin();
2097
2098
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2099
        $sql .= " statut = " . self::STATUS_RESILIATED;
2100
        $sql .= ", fk_user_valid=" . $user->id;
2101
        $sql .= " WHERE rowid = " . ((int) $this->id);
2102
2103
        $result = $this->db->query($sql);
2104
        if ($result) {
2105
            $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

2105
            /** @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...
2106
2107
            // Call trigger
2108
            $result = $this->call_trigger('MEMBER_RESILIATE', $user);
2109
            if ($result < 0) {
2110
                $error++;
2111
                $this->db->rollback();
2112
                return -1;
2113
            }
2114
            // End call triggers
2115
2116
            $this->db->commit();
2117
            return 1;
2118
        } else {
2119
            $this->error = $this->db->error();
2120
            $this->db->rollback();
2121
            return -1;
2122
        }
2123
    }
2124
2125
    /**
2126
     *      Functiun to exclude (set adherent.status to -2) a member
2127
     *      TODO
2128
     *      A private note should be added to know why the member has been excluded
2129
     *      For historical purpose it add an "extra-subscription" type excluded
2130
     *
2131
     * @param User $user User making change
2132
     *
2133
     * @return int                 Return integer <0 if KO, >0 if OK
2134
     */
2135
    public function exclude($user)
2136
    {
2137
        $error = 0;
2138
2139
        // Check parameters
2140
        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

2140
        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...
2141
            dol_syslog(get_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2142
            return 0;
2143
        }
2144
2145
        $this->db->begin();
2146
2147
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2148
        $sql .= " statut = " . self::STATUS_EXCLUDED;
2149
        $sql .= ", fk_user_valid=" . $user->id;
2150
        $sql .= " WHERE rowid = " . ((int) $this->id);
2151
2152
        $result = $this->db->query($sql);
2153
        if ($result) {
2154
            $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

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

2455
                $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...
2456
                    ($morecss ? ' usertext' . $morecss : '') . '">';
2457
            }
2458
            if ($mode == 'login') {
2459
                $result .= dol_trunc($this->login, $maxlen);
2460
            } elseif ($mode == 'ref') {
2461
                $result .= $this->ref;
2462
            } else {
2463
                $result .= $this->getFullName($langs, '', ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
2464
            }
2465
            if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
2466
                $result .= '</span>';
2467
            }
2468
        }
2469
        if ($withpictoimg) {
2470
            $result .= '</div>';
2471
        }
2472
        $result .= $linkend;
2473
2474
        if ($addlinktonotes) {
2475
            if ($this->note_private) {
2476
                $notetoshow = $langs->trans("ViewPrivateNote") . ':<br>' . dol_string_nohtmltag($this->note_private, 1);
2477
                $result .= ' <span class="note inline-block">';
2478
                $result .= '<a href="' . DOL_URL_ROOT . '/adherents/note.php?id=' . $this->id . '" class="classfortooltip" title="' . dol_escape_htmltag($notetoshow) . '">';
2479
                $result .= img_picto('', 'note');
2480
                $result .= '</a>';
2481
                $result .= '</span>';
2482
            }
2483
        }
2484
        global $action;
2485
        $hookmanager->initHooks([$this->element . 'dao']);
2486
        $parameters = ['id' => $this->id, 'getnomurl' => &$result];
2487
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2488
        if ($reshook > 0) {
2489
            $result = $hookmanager->resPrint;
2490
        } else {
2491
            $result .= $hookmanager->resPrint;
2492
        }
2493
        return $result;
2494
    }
2495
2496
    /**
2497
     *  Retourne le libelle du statut d'un adherent (brouillon, valide, resilie, exclu)
2498
     *
2499
     * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long,
2500
     *                  5=Libelle court + Picto
2501
     *
2502
     * @return string              Label
2503
     */
2504
    public function getLibStatut($mode = 0)
2505
    {
2506
        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

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

2666
                /** @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...
2667
2668
                if ($adherentstatic->hasDelay()) {
2669
                    $response->nbtodolate++;
2670
                }
2671
            }
2672
2673
            return $response;
2674
        } else {
2675
            dol_print_error($this->db);
2676
            $this->error = $this->db->error();
2677
            return -1;
2678
        }
2679
    }
2680
2681
2682
    /**
2683
     *  Create a document onto disk according to template module.
2684
     *
2685
     * @param string     $modele      Force template to use ('' to not force)
2686
     * @param Translate  $outputlangs object lang a utiliser pour traduction
2687
     * @param int        $hidedetails Hide details of lines
2688
     * @param int        $hidedesc    Hide description
2689
     * @param int        $hideref     Hide ref
2690
     * @param null|array $moreparams  Array to provide more information
2691
     *
2692
     * @return     int                         0 if KO, 1 if OK
2693
     */
2694
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2695
    {
2696
        global $conf, $langs;
2697
2698
        $langs->load("orders");
2699
2700
        if (!dol_strlen($modele)) {
2701
            $modele = 'standard';
2702
2703
            if ($this->model_pdf) {
2704
                $modele = $this->model_pdf;
2705
            } elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
2706
                $modele = getDolGlobalString('ADHERENT_ADDON_PDF');
2707
            }
2708
        }
2709
2710
        $modelpath = "core/modules/member/doc/";
2711
2712
        return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2713
    }
2714
2715
2716
    /**
2717
     *  Initialise an instance with random values.
2718
     *  Used to build previews or test instances.
2719
     *  id must be 0 if object instance is a specimen.
2720
     *
2721
     * @return int
2722
     */
2723
    public function initAsSpecimen()
2724
    {
2725
        global $user, $langs;
2726
        $now = dol_now();
2727
2728
        // Initialise parameters
2729
        $this->id = 0;
2730
        $this->ref = 'ABC001';
2731
        $this->entity = 1;
2732
        $this->specimen = 1;
2733
        $this->civility_id = 'MR';
2734
        $this->lastname = 'DOLIBARR';
2735
        $this->firstname = 'SPECIMEN';
2736
        $this->gender = 'man';
2737
        $this->login = 'dolibspec';
2738
        $this->pass = 'dolibspec';
2739
        $this->company = 'Societe ABC';
2740
        $this->address = '61 jump street';
2741
        $this->zip = '75000';
2742
        $this->town = 'Paris';
2743
        $this->country_id = 1;
2744
        $this->country_code = 'FR';
2745
        $this->country = 'France';
2746
        $this->morphy = 'mor';
2747
        $this->email = '[email protected]';
2748
        $this->socialnetworks = [
2749
            'skype' => 'skypepseudo',
2750
            'twitter' => 'twitterpseudo',
2751
            'facebook' => 'facebookpseudo',
2752
            'linkedin' => 'linkedinpseudo',
2753
        ];
2754
        $this->phone = '0999999999';
2755
        $this->phone_perso = '0999999998';
2756
        $this->phone_mobile = '0999999997';
2757
        $this->note_public = 'This is a public note';
2758
        $this->note_private = 'This is a private note';
2759
        $this->birth = $now;
2760
        $this->photo = '';
2761
        $this->public = 1;
2762
        $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

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

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

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