Passed
Push — dev ( f7d146...05f415 )
by Rafael
60:50
created

Adherent   F

Complexity

Total Complexity 507

Size/Duplication

Total Lines 3224
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 1723
dl 0
loc 3224
rs 0.8
c 0
b 0
f 0
wmc 507

42 Methods

Rating   Name   Duplication   Size   Complexity  
A send_an_email() 0 6 1
A __construct() 0 11 1
F fetch() 0 137 17
A hasDelay() 0 15 3
A fetch_name() 0 18 3
A fetch_subscriptions() 0 54 4
D makeSubstitution() 0 64 37
F delete() 0 80 14
A loadStateBoard() 0 22 3
A resiliate() 0 38 4
A fetch_login() 0 17 3
C setPassword() 0 85 14
A getLibStatut() 0 3 1
A fetchPartnerships() 0 7 1
A _load_ldap_dn() 0 15 4
A getNbOfEMailings() 0 17 2
A setThirdPartyId() 0 28 4
F getNomUrl() 0 115 41
C getKanbanView() 0 33 10
B subscription() 0 56 6
A getCivilityLabel() 0 10 3
B add_to_abo() 0 42 11
F create() 0 117 20
B del_to_abo() 0 42 10
F sendReminderForExpiredSubscription() 0 240 33
B sendEmail() 0 35 6
A update_end_date() 0 40 4
F update() 0 255 68
B load_board() 0 70 9
A setUserId() 0 32 4
C getTooltipContentArray() 0 49 12
A exclude() 0 36 4
F subscriptionComplementaryActions() 0 243 51
A validate() 0 43 4
A setCategories() 0 3 1
F _load_ldap_info() 0 142 66
B LibStatut() 0 43 8
A initAsSpecimen() 0 59 1
B getmorphylib() 0 42 11
A info() 0 28 3
A generateDocument() 0 19 4
A replaceThirdparty() 0 5 1

How to fix   Complexity   

Complex Class

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

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

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

1
<?php
2
3
/* Copyright (C) 2002-2003  Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2002-2003	Jean-Louis Bergamo		    <[email protected]>
5
 * Copyright (C) 2004-2012	Laurent Destailleur		    <[email protected]>
6
 * Copyright (C) 2004		Sebastien Di Cintio		    <[email protected]>
7
 * Copyright (C) 2004		Benoit Mortier			    <[email protected]>
8
 * Copyright (C) 2009-2017	Regis Houssin			    <[email protected]>
9
 * Copyright (C) 2014-2018	Alexandre Spangaro		    <[email protected]>
10
 * Copyright (C) 2015		Marcos García			    <[email protected]>
11
 * Copyright (C) 2015-2024	Frédéric France			    <[email protected]>
12
 * Copyright (C) 2015		Raphaël Doursenaud		    <[email protected]>
13
 * Copyright (C) 2016		Juanjo Menent			    <[email protected]>
14
 * Copyright (C) 2018-2019	Thibault FOUCART		    <[email protected]>
15
 * Copyright (C) 2019		Nicolas ZABOURI 		    <[email protected]>
16
 * Copyright (C) 2020		Josep Lluís Amador 		    <[email protected]>
17
 * Copyright (C) 2021		Waël Almoman                <[email protected]>
18
 * Copyright (C) 2021		Philippe Grand              <[email protected]>
19
 * Copyright (C) 2024		MDW							<[email protected]>
20
 * Copyright (C) 2024       Rafael San José             <[email protected]>
21
 *
22
 * This program is free software; you can redistribute it and/or modify
23
 * it under the terms of the GNU General Public License as published by
24
 * the Free Software Foundation; either version 3 of the License, or
25
 * (at your option) any later version.
26
 *
27
 * This program is distributed in the hope that it will be useful,
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30
 * GNU General Public License for more details.
31
 *
32
 * You should have received a copy of the GNU General Public License
33
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
34
 */
35
36
namespace Dolibarr\Code\Adherents\Classes;
37
38
/**
39
 *  \file       htdocs/adherents/class/adherent.class.php
40
 *  \ingroup    member
41
 *  \brief      File of class to manage members of a foundation
42
 */
43
44
use Dolibarr\Code\Categories\Classes\Categorie;
45
use Dolibarr\Code\Compta\Classes\Facture;
46
use Dolibarr\Code\Core\Classes\CMailFile;
47
use Dolibarr\Code\Core\Classes\Form;
48
use Dolibarr\Code\Core\Classes\WorkboardResponse;
49
use Dolibarr\Code\Core\Traits\CommonPeople;
50
use Dolibarr\Code\Societe\Classes\Societe;
51
use Dolibarr\Code\User\Classes\User;
52
use Dolibarr\Core\Base\CommonObject;
53
use DoliDB;
54
use Exception;
55
56
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php';
57
58
/**
59
 *      Class to manage members of a foundation
60
 */
61
class Adherent extends CommonObject
62
{
63
    use CommonPeople;
0 ignored issues
show
introduced by
The trait Dolibarr\Code\Core\Traits\CommonPeople requires some properties which are not provided by Dolibarr\Code\Adherents\Classes\Adherent: $MAIN_SHOW_REGION_IN_STATE_SELECT, $attributes, $global, $nom, $use_javascript_ajax, $office_fax
Loading history...
64
65
    /**
66
     * @var string ID to identify managed object
67
     */
68
    public $element = 'member';
69
70
    /**
71
     * @var string Name of table without prefix where object is stored
72
     */
73
    public $table_element = 'adherent';
74
75
    /**
76
     * @var string picto
77
     */
78
    public $picto = 'member';
79
80
    /**
81
     * @var string[] array of messages
82
     */
83
    public $mesgs;
84
85
    /**
86
     * @var string login of member
87
     */
88
    public $login;
89
90
    /**
91
     * @var string Clear password in memory
92
     */
93
    public $pass;
94
95
    /**
96
     * @var string Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
97
     */
98
    public $pass_indatabase;
99
100
    /**
101
     * @var string Encrypted password in database (always defined)
102
     */
103
    public $pass_indatabase_crypted;
104
105
    /**
106
     * @var string fullname
107
     */
108
    public $fullname;
109
110
    /**
111
     * @var string
112
     * @deprecated
113
     * @see $civility_code
114
     */
115
    public $civility_id;
116
117
    /**
118
     * @var string The civility code, not an integer (ex: 'MR', 'MME', 'MLE', etc.)
119
     */
120
    public $civility_code;
121
122
    public $civility;
123
124
    /**
125
     * @var string company name
126
     * @deprecated
127
     * @see $company
128
     */
129
    public $societe;
130
131
    /**
132
     * @var string company name
133
     */
134
    public $company;
135
136
    /**
137
     * @var int Thirdparty ID
138
     * @deprecated
139
     * @see $socid
140
     */
141
    public $fk_soc;
142
143
    /**
144
     * @var int socid
145
     */
146
    public $socid;
147
148
    /**
149
     * @var array array of socialnetworks
150
     */
151
    public $socialnetworks;
152
153
    /**
154
     * @var string Phone number
155
     */
156
    public $phone;
157
158
    /**
159
     * @var string Private Phone number
160
     */
161
    public $phone_perso;
162
163
    /**
164
     * @var string Professional Phone number
165
     */
166
    public $phone_pro;
167
168
    /**
169
     * @var string Mobile phone number
170
     */
171
    public $phone_mobile;
172
173
    /**
174
     * @var string Fax number
175
     */
176
    public $fax;
177
178
    /**
179
     * @var string Function
180
     */
181
    public $poste;
182
183
    /**
184
     * @var string mor or phy
185
     */
186
    public $morphy;
187
188
    /**
189
     * @var int Info can be public
190
     */
191
    public $public;
192
193
    /**
194
     * Default language code of member (en_US, ...)
195
     * @var string
196
     */
197
    public $default_lang;
198
199
    /**
200
     * @var string photo of member
201
     */
202
    public $photo;
203
204
    /**
205
     * Date creation record (datec)
206
     *
207
     * @var integer
208
     */
209
    public $datec;
210
211
    /**
212
     * Date modification record (tms)
213
     *
214
     * @var integer
215
     */
216
    public $datem;
217
218
    public $datevalid;
219
220
    /**
221
     * @var string gender
222
     */
223
    public $gender;
224
225
    /**
226
     * @var int|string date of birth
227
     */
228
    public $birth;
229
230
    /**
231
     * @var int id type member
232
     */
233
    public $typeid;
234
235
    /**
236
     * @var string label type member
237
     */
238
    public $type;
239
240
    /**
241
     * @var int need_subscription
242
     */
243
    public $need_subscription;
244
245
    /**
246
     * @var int user_id
247
     */
248
    public $user_id;
249
250
    /**
251
     * @var string user_login
252
     */
253
    public $user_login;
254
255
    public $datefin;
256
257
258
    // Fields loaded by fetch_subscriptions() from member table
259
260
    /**
261
     * @var int|string date
262
     */
263
    public $first_subscription_date;
264
265
    /**
266
     * @var int|string date
267
     */
268
    public $first_subscription_date_start;
269
270
    /**
271
     * @var int|string date
272
     */
273
    public $first_subscription_date_end;
274
275
    /**
276
     * @var int|string date
277
     */
278
    public $first_subscription_amount;
279
280
    /**
281
     * @var int|string date
282
     */
283
    public $last_subscription_date;
284
285
    /**
286
     * @var int|string date
287
     */
288
    public $last_subscription_date_start;
289
290
    /**
291
     * @var int|string date
292
     */
293
    public $last_subscription_date_end;
294
295
    /**
296
     * @var int|string date
297
     */
298
    public $last_subscription_amount;
299
300
    /**
301
     * @var array
302
     */
303
    public $subscriptions = array();
304
305
    /**
306
     * @var string ip
307
     */
308
    public $ip;
309
310
    // Fields loaded by fetchPartnerships() from partnership table
311
312
    public $partnerships = array();
313
314
    /**
315
     * @var Facture|null        To store the created invoice into subscriptionComplementaryActions()
316
     */
317
    public $invoice;
318
319
320
    /**
321
     * @var array<string,array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}>  Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,array{type:...ring>,comment?:string}> at position 16 could not be parsed: Expected '}' at position 16, but found 'int'.
Loading history...
322
     */
323
    public $fields = array(
324
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
325
        'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
326
        'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 15, 'index' => 1),
327
        'ref_ext' => array('type' => 'varchar(128)', 'label' => 'Ref ext', 'enabled' => 1, 'visible' => 0, 'position' => 20),
328
        'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
329
        'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
330
        'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
331
        'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => 1, 'position' => 40),
332
        'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => -1, 'position' => 45),
333
        'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => -1, 'position' => 50),
334
        'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
335
        'fk_adherent_type' => array('type' => 'integer', 'label' => 'Fk adherent type', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
336
        'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
337
        'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
338
        'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
339
        'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
340
        'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
341
        'state_id' => array('type' => 'integer', 'label' => 'State id', 'enabled' => 1, 'visible' => -1, 'position' => 90),
342
        'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
343
        'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
344
        'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
345
        'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
346
        'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
347
        'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
348
        'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => -1, 'position' => 128),
349
        'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
350
        'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
351
        'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
352
        'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 145),
353
        'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
354
        'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
355
        'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
356
        'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
357
        'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
358
        'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
359
        'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
360
        'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 180),
361
        'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user mod', 'enabled' => 1, 'visible' => -1, 'position' => 185),
362
        'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 190),
363
        'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => -1, 'position' => 195),
364
        'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 500, 'arrayofkeyval' => array(-1 => 'Draft', 1 => 'Validated', 0 => 'MemberStatusResiliatedShort', -2 => 'MemberStatusExcludedShort')),
365
        'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
366
        'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805)
367
    );
368
369
    /**
370
     * Draft status
371
     */
372
    const STATUS_DRAFT = -1;
373
    /**
374
     * Validated status
375
     */
376
    const STATUS_VALIDATED = 1;
377
    /**
378
     * Resiliated
379
     */
380
    const STATUS_RESILIATED = 0;
381
    /**
382
     * Excluded
383
     */
384
    const STATUS_EXCLUDED = -2;
385
386
387
    /**
388
     *  Constructor
389
     *
390
     *  @param      DoliDB      $db     Database handler
391
     */
392
    public function __construct($db)
393
    {
394
        $this->db = $db;
395
        $this->statut = self::STATUS_DRAFT;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$statut has been deprecated: Use $status instead. ( Ignorable by Annotation )

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

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

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

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

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

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

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

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

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

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

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

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

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

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

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

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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