Passed
Pull Request — dev (#8)
by Rafael
58:47
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  
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
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
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
A send_an_email() 0 6 1
A __construct() 0 11 1
C getKanbanView() 0 33 10
F sendReminderForExpiredSubscription() 0 240 33
B sendEmail() 0 35 6

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

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

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

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

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

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

1978
        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...
1979
            dol_syslog(get_class($this) . "::validate statut of member does not allow this", LOG_WARNING);
1980
            return 0;
1981
        }
1982
1983
        $this->db->begin();
1984
1985
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
1986
        $sql .= " statut = " . self::STATUS_VALIDATED;
1987
        $sql .= ", datevalid = '" . $this->db->idate($now) . "'";
1988
        $sql .= ", fk_user_valid = " . ((int) $user->id);
1989
        $sql .= " WHERE rowid = " . ((int) $this->id);
1990
1991
        dol_syslog(get_class($this) . "::validate", LOG_DEBUG);
1992
        $result = $this->db->query($sql);
1993
        if ($result) {
1994
            $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

1994
            /** @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...
1995
1996
            // Call trigger
1997
            $result = $this->call_trigger('MEMBER_VALIDATE', $user);
1998
            if ($result < 0) {
1999
                $error++;
2000
                $this->db->rollback();
2001
                return -1;
2002
            }
2003
            // End call triggers
2004
2005
            $this->datevalid = $now;
2006
2007
            $this->db->commit();
2008
            return 1;
2009
        } else {
2010
            $this->error = $this->db->error();
2011
            $this->db->rollback();
2012
            return -1;
2013
        }
2014
    }
2015
2016
2017
    /**
2018
     *      Fonction qui resilie un adherent
2019
     *
2020
     *      @param  User    $user       User making change
2021
     *      @return int                 Return integer <0 if KO, >0 if OK
2022
     */
2023
    public function resiliate($user)
2024
    {
2025
        global $langs, $conf;
2026
2027
        $error = 0;
2028
2029
        // Check parameters
2030
        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

2030
        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...
2031
            dol_syslog(get_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2032
            return 0;
2033
        }
2034
2035
        $this->db->begin();
2036
2037
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2038
        $sql .= " statut = " . self::STATUS_RESILIATED;
2039
        $sql .= ", fk_user_valid=" . $user->id;
2040
        $sql .= " WHERE rowid = " . ((int) $this->id);
2041
2042
        $result = $this->db->query($sql);
2043
        if ($result) {
2044
            $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

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

2078
        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...
2079
            dol_syslog(get_class($this) . "::resiliate statut of member does not allow this", LOG_WARNING);
2080
            return 0;
2081
        }
2082
2083
        $this->db->begin();
2084
2085
        $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent SET";
2086
        $sql .= " statut = " . self::STATUS_EXCLUDED;
2087
        $sql .= ", fk_user_valid=" . $user->id;
2088
        $sql .= " WHERE rowid = " . ((int) $this->id);
2089
2090
        $result = $this->db->query($sql);
2091
        if ($result) {
2092
            $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

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

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

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

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

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

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

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