Passed
Branch develop (5cbde9)
by
unknown
26:38
created

Adherent::subscription()   B

Complexity

Conditions 6

Size

Total Lines 65
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 36
c 0
b 0
f 0
nop 9
dl 0
loc 65
rs 8.7217

How to fix   Long Method    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 2002-2003	Rodolphe Quiedeville	<[email protected]>
3
 * Copyright (C) 2002-2003	Jean-Louis Bergamo		<[email protected]>
4
 * Copyright (C) 2004-2012	Laurent Destailleur		<[email protected]>
5
 * Copyright (C) 2004		Sebastien Di Cintio		<[email protected]>
6
 * Copyright (C) 2004		Benoit Mortier			<[email protected]>
7
 * Copyright (C) 2009-2017	Regis Houssin			<[email protected]>
8
 * Copyright (C) 2014-2018	Alexandre Spangaro		<[email protected]>
9
 * Copyright (C) 2015		Marcos García			<[email protected]>
10
 * Copyright (C) 2015-2018  Frédéric France			<[email protected]>
11
 * Copyright (C) 2015		Raphaël Doursenaud		<[email protected]>
12
 * Copyright (C) 2016		Juanjo Menent			<[email protected]>
13
 * Copyright (C) 2018-2019  Thibault FOUCART		<[email protected]>
14
 * Copyright (C) 2019       Nicolas ZABOURI 		<[email protected]>
15
 *
16
 * This program is free software; you can redistribute it and/or modify
17
 * it under the terms of the GNU General Public License as published by
18
 * the Free Software Foundation; either version 3 of the License, or
19
 * (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28
 */
29
30
/**
31
 *	\file       htdocs/adherents/class/adherent.class.php
32
 *	\ingroup    member
33
 *	\brief      File of class to manage members of a foundation
34
 */
35
36
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
37
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
38
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
39
40
41
/**
42
 *		Class to manage members of a foundation
43
 */
44
class Adherent extends CommonObject
45
{
46
	/**
47
	 * @var string ID to identify managed object
48
	 */
49
	public $element='member';
50
51
	/**
52
	 * @var string Name of table without prefix where object is stored
53
	 */
54
	public $table_element='adherent';
55
56
	/**
57
	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
58
	 * @var int
59
	 */
60
	public $ismultientitymanaged = 1;
61
62
	public $mesgs;
63
64
    /**
65
     * @var string login of member
66
     */
67
	public $login;
68
69
	//! Clear password in memory
70
	public $pass;
71
	//! Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
72
	public $pass_indatabase;
73
	//! Encrypted password in database (always defined)
74
	public $pass_indatabase_crypted;
75
76
    /**
77
     * @var string company name
78
     * @deprecated
79
     */
80
	public $societe;
81
82
	/**
83
	 * @var string company name
84
	 */
85
	public $company;
86
87
	/**
88
	 * @var int Thirdparty ID
89
	 */
90
    public $fk_soc;
91
92
	/**
93
	 * @var string Address
94
	 */
95
	public $address;
96
97
    /**
98
     * @var string zipcode
99
     */
100
    public $zip;
101
102
    /**
103
     * @var string town
104
     */
105
	public $town;
106
107
    /**
108
     * @var int Id of state
109
     */
110
    public $state_id;
111
112
    /**
113
     * @var string Code of state
114
     */
115
    public $state_code;
116
117
    /**
118
     * @var string Label of state
119
     */
120
	public $state;
121
122
    /**
123
     * @var string email
124
     */
125
	public $email;
126
127
    /**
128
     * @var string skype account
129
     */
130
    public $skype;
131
132
    /**
133
     * @var string twitter account
134
     */
135
    public $twitter;
136
137
    /**
138
     * @var string facebook account
139
     */
140
	public $facebook;
141
142
    /**
143
     * @var string linkedin account
144
     */
145
    public $linkedin;
146
147
    /**
148
     * @var string Phone number
149
     */
150
	public $phone;
151
152
    /**
153
     * @var string Private Phone number
154
     */
155
	public $phone_perso;
156
157
    /**
158
     * @var string Mobile phone number
159
     */
160
	public $phone_mobile;
161
162
    /**
163
     * @var string Fax number
164
     */
165
    public $fax;
166
167
    /**
168
     * @var string Function
169
     */
170
    public $poste;
171
172
	public $morphy;
173
	public $public;
174
175
    // -1:brouillon, 0:resilie, >=1:valide,paye
176
    // def in common object
177
    //public $statut;
178
179
    public $photo;
180
181
	/**
182
     * Date creation record (datec)
183
     *
184
     * @var integer
185
     */
186
    public $datec;
187
188
	/**
189
     * Date modification record (tms)
190
     *
191
     * @var integer
192
     */
193
    public $datem;
194
195
	public $datevalid;
196
197
	public $gender;
198
	public $birth;
199
200
    /**
201
     * @var int id type member
202
     */
203
	public $typeid;
204
205
    /**
206
     * @var string label type member
207
     */
208
	public $type;
209
	public $need_subscription;
210
211
	public $user_id;
212
	public $user_login;
213
214
	public $datefin;	// From member table
215
216
	// Fields loaded by fetch_subscriptions()
217
	public $first_subscription_date;
218
	public $first_subscription_amount;
219
	public $last_subscription_date;
220
	public $last_subscription_date_start;
221
	public $last_subscription_date_end;
222
	public $last_subscription_amount;
223
	public $subscriptions=array();
224
225
    /**
226
     * @var Adherent To contains a clone of this when we need to save old properties of object
227
     */
228
	public $oldcopy;
229
230
	/**
231
	 * @var int Entity
232
	 */
233
	public $entity;
234
235
	/**
236
	 *	Constructor
237
	 *
238
	 *	@param 		DoliDB		$db		Database handler
239
	 */
240
	public function __construct($db)
241
	{
242
		$this->db = $db;
243
		$this->statut = -1;
244
		// l'adherent n'est pas public par defaut
245
		$this->public = 0;
246
		// les champs optionnels sont vides
247
		$this->array_options=array();
248
	}
249
250
251
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
252
	/**
253
	 *  Function sending an email to the current member with the text supplied in parameter.
254
	 *
255
	 *  @param	string	$text				Content of message (not html entities encoded)
256
	 *  @param	string	$subject			Subject of message
257
	 *  @param 	array	$filename_list      Array of attached files
258
	 *  @param 	array	$mimetype_list      Array of mime types of attached files
259
	 *  @param 	array	$mimefilename_list  Array of public names of attached files
260
	 *  @param 	string	$addr_cc            Email cc
261
	 *  @param 	string	$addr_bcc           Email bcc
262
	 *  @param 	int		$deliveryreceipt	Ask a delivery receipt
263
	 *  @param	int		$msgishtml			1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
264
	 *  @param	string	$errors_to			erros to
265
	 *  @param	string	$moreinheader		Add more html headers
266
	 *  @return	int							<0 if KO, >0 if OK
267
	 */
268
	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 = '')
269
	{
270
        // phpcs:enable
271
		global $conf,$langs;
272
273
		// Detect if message is HTML
274
		if ($msgishtml == -1)
275
		{
276
			$msgishtml = 0;
277
			if (dol_textishtml($text, 0)) $msgishtml = 1;
278
		}
279
280
		dol_syslog('send_an_email msgishtml='.$msgishtml);
281
282
		$texttosend=$this->makeSubstitution($text);
283
		$subjecttosend=$this->makeSubstitution($subject);
284
		if ($msgishtml) $texttosend=dol_htmlentitiesbr($texttosend);
285
286
		// Envoi mail confirmation
287
		$from=$conf->email_from;
288
		if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM;
289
290
		$trackid = 'mem'.$this->id;
291
292
		// Send email (substitutionarray must be done just before this)
293
		include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
294
		$mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
295
		if ($mailfile->sendfile())
296
		{
297
			return 1;
298
		}
299
		else
300
		{
301
			$this->error=$langs->trans("ErrorFailedToSendMail", $from, $this->email).'. '.$mailfile->error;
302
			return -1;
303
		}
304
	}
305
306
307
	/**
308
	 * Make substitution of tags into text with value of current object.
309
	 *
310
	 * @param	string	$text       Text to make substitution to
311
	 * @return  string      		Value of input text string with substitutions done
312
	 */
313
	public function makeSubstitution($text)
314
	{
315
		global $conf,$langs;
316
317
		$birthday = dol_print_date($this->birth, 'day');
318
319
		$msgishtml = 0;
320
		if (dol_textishtml($text, 1)) $msgishtml = 1;
321
322
		$infos='';
323
		if ($this->civility_id) $infos.= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
324
		$infos.= $langs->transnoentities("id").": ".$this->id."\n";
325
		$infos.= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
326
		$infos.= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
327
		$infos.= $langs->transnoentities("Company").": ".$this->societe."\n";
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

327
		$infos.= $langs->transnoentities("Company").": "./** @scrutinizer ignore-deprecated */ $this->societe."\n";
Loading history...
328
		$infos.= $langs->transnoentities("Address").": ".$this->address."\n";
329
		$infos.= $langs->transnoentities("Zip").": ".$this->zip."\n";
330
		$infos.= $langs->transnoentities("Town").": ".$this->town."\n";
331
		$infos.= $langs->transnoentities("Country").": ".$this->country."\n";
332
		$infos.= $langs->transnoentities("EMail").": ".$this->email."\n";
333
		$infos.= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
334
		$infos.= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
335
		$infos.= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
336
		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
337
		{
338
			$infos.= $langs->transnoentities("Login").": ".$this->login."\n";
339
			$infos.= $langs->transnoentities("Password").": ".$this->pass."\n";
340
		}
341
		$infos.= $langs->transnoentities("Birthday").": ".$birthday."\n";
342
		$infos.= $langs->transnoentities("Photo").": ".$this->photo."\n";
343
		$infos.= $langs->transnoentities("Public").": ".yn($this->public);
344
345
		// Substitutions
346
		$substitutionarray=array(
347
		    '__ID__'=>$this->id,
348
		    '__MEMBER_ID__'=>$this->id,
349
			'__CIVILITY__'=>$this->getCivilityLabel(),
350
			'__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):($this->firstname?$this->firstname:''),
351
			'__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):($this->lastname?$this->lastname:''),
352
			'__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs),
353
			'__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):($this->societe?$this->societe:''),
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

353
			'__COMPANY__'=>$msgishtml?dol_htmlentitiesbr(/** @scrutinizer ignore-deprecated */ $this->societe):($this->societe?$this->societe:''),
Loading history...
354
			'__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):($this->address?$this->address:''),
355
			'__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):($this->zip?$this->zip:''),
356
			'__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):($this->town?$this->town:''),
357
			'__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):($this->country?$this->country:''),
358
			'__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):($this->email?$this->email:''),
359
			'__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):($birthday?$birthday:''),
360
			'__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):($this->photo?$this->photo:''),
361
			'__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):($this->login?$this->login:''),
362
			'__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):($this->pass?$this->pass:''),
363
			'__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):($this->phone?$this->phone:''),
364
			'__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):($this->phone_perso?$this->phone_perso:''),
365
			'__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):($this->phone_mobile?$this->phone_mobile:'')
366
		);
367
368
		complete_substitutions_array($substitutionarray, $langs, $this);
369
370
		return make_substitutions($text, $substitutionarray, $langs);
371
	}
372
373
374
	/**
375
	 *	Return translated label by the nature of a adherent (physical or moral)
376
	 *
377
	 *	@param	string		$morphy		Nature of the adherent (physical or moral)
378
	 *	@return	string					Label
379
	 */
380
	public function getmorphylib($morphy = '')
381
	{
382
		global $langs;
383
		if (! $morphy) { $morphy=$this->morphy; }
384
		if ($morphy == 'phy') { return $langs->trans("Physical"); }
385
		if ($morphy == 'mor') { return $langs->trans("Moral"); }
386
		return $morphy;
387
	}
388
389
	/**
390
	 *	Create a member into database
391
	 *
392
	 *	@param	User	$user        	Objet user qui demande la creation
393
	 *	@param  int		$notrigger		1 ne declenche pas les triggers, 0 sinon
394
	 *	@return	int						<0 if KO, >0 if OK
395
	 */
396
	public function create($user, $notrigger = 0)
397
	{
398
		global $conf,$langs;
399
400
		$error=0;
401
402
		$now=dol_now();
403
404
		// Clean parameters
405
		$this->import_key = trim($this->import_key);
406
407
		// Check parameters
408
		if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
409
		{
410
			$langs->load("errors");
411
			$this->error = $langs->trans("ErrorBadEMail", $this->email);
412
			return -1;
413
		}
414
		if (! $this->datec) $this->datec=$now;
415
		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
416
		{
417
			if (empty($this->login))
418
			{
419
				$this->error = $langs->trans("ErrorWrongValueForParameterX", "Login");
420
				return -1;
421
			}
422
		}
423
424
		$this->db->begin();
425
426
		// Insert member
427
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
428
		$sql.= " (datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key)";
429
		$sql.= " VALUES (";
430
		$sql.= " '".$this->db->idate($this->datec)."'";
431
		$sql.= ", ".($this->login?"'".$this->db->escape($this->login)."'":"null");
432
		$sql.= ", ".($user->id>0?$user->id:"null");	// Can be null because member can be created by a guest or a script
433
		$sql.= ", null, null, '".$this->db->escape($this->morphy)."'";
434
		$sql.= ", ".$this->typeid;
435
		$sql.= ", ".$conf->entity;
436
		$sql.= ", ".(! empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'":"null");
437
		$sql.= ")";
438
439
		dol_syslog(get_class($this)."::create", LOG_DEBUG);
440
		$result = $this->db->query($sql);
441
		if ($result)
442
		{
443
			$id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
444
			if ($id > 0)
445
			{
446
				$this->id=$id;
447
				$this->ref=(string) $id;
448
449
				// Update minor fields
450
				$result=$this->update($user, 1, 1, 0, 0, 'add'); // nosync is 1 to avoid update data of user
451
				if ($result < 0)
452
				{
453
					$this->db->rollback();
454
					return -1;
455
				}
456
457
				// Add link to user
458
				if ($this->user_id)
459
				{
460
					// Add link to user
461
					$sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
462
					$sql.= " fk_member = ".$this->id;
463
					$sql.= " WHERE rowid = ".$this->user_id;
464
					dol_syslog(get_class($this)."::create", LOG_DEBUG);
465
					$resql = $this->db->query($sql);
466
					if (! $resql)
467
					{
468
						$this->error='Failed to update user to make link with member';
469
						$this->db->rollback();
470
						return -4;
471
					}
472
				}
473
474
				if (! $notrigger)
475
				{
476
					// Call trigger
477
					$result=$this->call_trigger('MEMBER_CREATE', $user);
478
					if ($result < 0) { $error++; }
479
					// End call triggers
480
				}
481
482
				if (count($this->errors))
483
				{
484
					dol_syslog(get_class($this)."::create ".implode(',', $this->errors), LOG_ERR);
485
					$this->db->rollback();
486
					return -3;
487
				}
488
				else
489
				{
490
					$this->db->commit();
491
					return $this->id;
492
				}
493
			}
494
			else
495
			{
496
				$this->error='Failed to get last insert id';
497
				dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
498
				$this->db->rollback();
499
				return -2;
500
			}
501
		}
502
		else
503
		{
504
			$this->error=$this->db->error();
505
			$this->db->rollback();
506
			return -1;
507
		}
508
	}
509
510
511
	/**
512
	 *	Update a member in database (standard information and password)
513
	 *
514
	 *	@param	User	$user				User making update
515
	 *	@param	int		$notrigger			1=disable trigger UPDATE (when called by create)
516
	 *	@param	int		$nosyncuser			0=Synchronize linked user (standard info), 1=Do not synchronize linked user
517
	 *	@param	int		$nosyncuserpass		0=Synchronize linked user (password), 1=Do not synchronize linked user
518
	 *	@param	int		$nosyncthirdparty	0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty
519
	 * 	@param	string	$action				Current action for hookmanager
520
	 * 	@return	int							<0 if KO, >0 if OK
521
	 */
522
	public function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
523
	{
524
		global $conf, $langs, $hookmanager;
525
526
		$nbrowsaffected=0;
527
		$error=0;
528
529
		dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
530
531
		// Clean parameters
532
		$this->lastname     = trim($this->lastname)?trim($this->lastname):trim($this->lastname);
533
		$this->firstname    = trim($this->firstname)?trim($this->firstname):trim($this->firstname);
534
		$this->gender       = trim($this->gender);
535
		$this->address      = ($this->address?$this->address:$this->address);
536
		$this->zip          = ($this->zip?$this->zip:$this->zip);
537
		$this->town         = ($this->town?$this->town:$this->town);
538
		$this->country_id   = ($this->country_id > 0?$this->country_id:$this->country_id);
539
		$this->state_id     = ($this->state_id > 0?$this->state_id:$this->state_id);
540
		if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname=ucwords(trim($this->lastname));
541
		if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname));
542
		$this->note_public  = ($this->note_public?$this->note_public:$this->note_public);
543
		$this->note_private = ($this->note_private?$this->note_private:$this->note_private);
544
545
		// Check parameters
546
		if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
547
		{
548
			$langs->load("errors");
549
			$this->error = $langs->trans("ErrorBadEMail", $this->email);
550
			return -1;
551
		}
552
553
		$this->db->begin();
554
555
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
556
		$sql.= " civility = ".($this->civility_id?"'".$this->db->escape($this->civility_id)."'":"null");
557
		$sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null");
558
		$sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null");
559
		$sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null");	// 'man' or 'woman'
560
		$sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null");
561
		$sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null");
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

561
		$sql.= ", societe = ".(/** @scrutinizer ignore-deprecated */ $this->societe?"'".$this->db->escape($this->societe)."'":"null");
Loading history...
562
		$sql.= ", fk_soc = ".($this->socid > 0?$this->db->escape($this->socid):"null");
563
		$sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null");
564
		$sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null");
565
		$sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null");
566
		$sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null");
567
		$sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null");
568
		$sql.= ", email = '".$this->db->escape($this->email)."'";
569
		$sql.= ", skype = '".$this->db->escape($this->skype)."'";
570
		$sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
571
		$sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
572
		$sql.= ", linkedin = '".$this->db->escape($this->linkedin)."'";
573
		$sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null");
574
		$sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null");
575
		$sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null");
576
		$sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
577
		$sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
578
		$sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null");
579
		$sql.= ", public = '".$this->db->escape($this->public)."'";
580
		$sql.= ", statut = ".$this->db->escape($this->statut);
581
		$sql.= ", fk_adherent_type = ".$this->db->escape($this->typeid);
582
		$sql.= ", morphy = '".$this->db->escape($this->morphy)."'";
583
		$sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null");
584
		if ($this->datefin)   $sql.= ", datefin = '".$this->db->idate($this->datefin)."'";		// Must be modified only when deleting a subscription
585
		if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'";	// Must be modified only when validating a member
586
		$sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null');	// Can be null because member can be create by a guest
587
		$sql.= " WHERE rowid = ".$this->id;
588
589
		// If we change the type of membership, we set also label of new type
590
		if (! empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid)
591
		{
592
			$sql2 = "SELECT libelle as label";
593
			$sql2.= " FROM ".MAIN_DB_PREFIX."adherent_type";
594
			$sql2.= " WHERE rowid = ".$this->typeid;
595
			$resql2 = $this->db->query($sql2);
596
			if ($resql2)
597
			{
598
			    while ($obj=$this->db->fetch_object($resql2))
599
			    {
600
					$this->type=$obj->label;
601
			    }
602
			}
603
		}
604
605
		dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
606
		$resql = $this->db->query($sql);
607
		if ($resql)
608
		{
609
			unset($this->country_code);
610
			unset($this->country);
611
			unset($this->state_code);
612
			unset($this->state);
613
614
			$nbrowsaffected+=$this->db->affected_rows($resql);
615
616
			$action='update';
617
618
			// Actions on extra fields
619
			if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
620
			{
621
				$result=$this->insertExtraFields();
622
				if ($result < 0)
623
				{
624
					$error++;
625
				}
626
			}
627
628
			// Update password
629
			if (! $error && $this->pass)
630
			{
631
				dol_syslog(get_class($this)."::update update password");
632
				if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted)
633
				{
634
					$isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1;
635
636
					// If password to set differs from the one found into database
637
					$result=$this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
638
					if (! $nbrowsaffected) $nbrowsaffected++;
639
				}
640
			}
641
642
			// Remove links to user and replace with new one
643
			if (! $error)
644
			{
645
				dol_syslog(get_class($this)."::update update link to user");
646
				$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
647
				dol_syslog(get_class($this)."::update", LOG_DEBUG);
648
				$resql = $this->db->query($sql);
649
				if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
650
				// If there is a user linked to this member
651
				if ($this->user_id > 0)
652
				{
653
					$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id." WHERE rowid = ".$this->user_id;
654
					dol_syslog(get_class($this)."::update", LOG_DEBUG);
655
					$resql = $this->db->query($sql);
656
					if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
657
				}
658
			}
659
660
			if (! $error && $nbrowsaffected)	// If something has change in main data
661
			{
662
				// Update information on linked user if it is an update
663
				if (! $error && $this->user_id > 0 && ! $nosyncuser)
664
				{
665
					require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
666
667
					dol_syslog(get_class($this)."::update update linked user");
668
669
					$luser=new User($this->db);
670
					$result=$luser->fetch($this->user_id);
671
672
					if ($result >= 0)
673
					{
674
						//var_dump($this->user_login);exit;
675
						//var_dump($this->login);exit;
676
677
						// 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.
678
						if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) $luser->login=$this->login;
679
680
						$luser->civility_id=$this->civility_id;
681
						$luser->firstname=$this->firstname;
682
						$luser->lastname=$this->lastname;
683
						$luser->gender=$this->gender;
684
						$luser->pass=$this->pass;
685
						$luser->societe_id=$this->societe;
686
687
						$luser->birth=$this->birth;
688
689
						$luser->address=$this->address;
690
						$luser->zip=$this->zip;
691
						$luser->town=$this->town;
692
						$luser->country_id=$this->country_id;
693
						$luser->state_id=$this->state_id;
694
695
						$luser->email=$this->email;
696
						$luser->skype=$this->skype;
697
						$luser->twitter=$this->twitter;
698
						$luser->facebook=$this->facebook;
699
						$luser->linkedin=$this->linkedin;
700
						$luser->office_phone=$this->phone;
701
						$luser->user_mobile=$this->phone_mobile;
702
703
						$luser->fk_member=$this->id;
704
705
						$result=$luser->update($user, 0, 1, 1);	// Use nosync to 1 to avoid cyclic updates
706
						if ($result < 0)
707
						{
708
							$this->error=$luser->error;
709
							dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
710
							$error++;
711
						}
712
					}
713
					else
714
					{
715
						$this->error=$luser->error;
716
						$error++;
717
					}
718
				}
719
720
				// Update information on linked thirdparty if it is an update
721
				if (! $error && $this->fk_soc > 0 && ! $nosyncthirdparty)
722
				{
723
					require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
724
725
					dol_syslog(get_class($this)."::update update linked thirdparty");
726
727
					// This member is linked with a thirdparty, so we also update thirdparty informations
728
					// if this is an update.
729
					$lthirdparty=new Societe($this->db);
730
					$result=$lthirdparty->fetch($this->fk_soc);
731
732
					if ($result > 0)
733
					{
734
						$lthirdparty->address=$this->address;
735
						$lthirdparty->zip=$this->zip;
736
						$lthirdparty->town=$this->town;
737
						$lthirdparty->email=$this->email;
738
						$lthirdparty->skype=$this->skype;
739
						$lthirdparty->twitter=$this->twitter;
740
						$lthirdparty->facebook=$this->facebook;
741
						$lthirdparty->linkedin=$this->linkedin;
742
						$lthirdparty->phone=$this->phone;
743
						$lthirdparty->state_id=$this->state_id;
744
						$lthirdparty->country_id=$this->country_id;
745
						//$lthirdparty->phone_mobile=$this->phone_mobile;
746
747
						$result=$lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update');	// Use sync to 0 to avoid cyclic updates
748
749
						if ($result < 0)
750
						{
751
							$this->error=$lthirdparty->error;
752
							$this->errors=$lthirdparty->errors;
753
							dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
754
							$error++;
755
						}
756
					}
757
					elseif ($result < 0)
758
					{
759
						$this->error=$lthirdparty->error;
760
						$error++;
761
					}
762
				}
763
			}
764
765
			if (! $error && ! $notrigger)
766
			{
767
				// Call trigger
768
				$result=$this->call_trigger('MEMBER_MODIFY', $user);
769
				if ($result < 0) { $error++; }
770
				// End call triggers
771
			}
772
773
			if (! $error)
774
			{
775
				$this->db->commit();
776
				return $nbrowsaffected;
777
			}
778
			else
779
			{
780
				$this->db->rollback();
781
				return -1;
782
			}
783
		}
784
		else
785
		{
786
			$this->db->rollback();
787
			$this->error=$this->db->lasterror();
788
			return -2;
789
		}
790
	}
791
792
793
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
794
	/**
795
	 *	Update denormalized last subscription date.
796
	 * 	This function is called when we delete a subscription for example.
797
	 *
798
	 *	@param	User	$user			User making change
799
	 *	@return	int						<0 if KO, >0 if OK
800
	 */
801
	public function update_end_date($user)
802
	{
803
        // phpcs:enable
804
		$this->db->begin();
805
806
		// Search for last subscription id and end date
807
		$sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
808
		$sql.= " FROM ".MAIN_DB_PREFIX."subscription";
809
		$sql.= " WHERE fk_adherent=".$this->id;
810
		$sql.= " ORDER by dateadh DESC";	// Sort by start subscription date
811
812
		dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
813
		$resql=$this->db->query($sql);
814
		if ($resql)
815
		{
816
			$obj=$this->db->fetch_object($resql);
817
			$dateop=$this->db->jdate($obj->dateop);
818
			$datedeb=$this->db->jdate($obj->datedeb);
819
			$datefin=$this->db->jdate($obj->datefin);
820
821
			$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
822
			$sql.= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
823
			$sql.= " WHERE rowid = ".$this->id;
824
825
			dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
826
			$resql=$this->db->query($sql);
827
			if ($resql)
828
			{
829
				$this->last_subscription_date=$dateop;
830
				$this->last_subscription_date_start=$datedeb;
831
				$this->last_subscription_date_end=$datefin;
832
				$this->datefin=$datefin;
833
				$this->db->commit();
834
				return 1;
835
			}
836
			else
837
			{
838
				$this->db->rollback();
839
				return -1;
840
			}
841
		}
842
		else
843
		{
844
			$this->error=$this->db->lasterror();
845
			$this->db->rollback();
846
			return -1;
847
		}
848
	}
849
850
	/**
851
	 *  Fonction qui supprime l'adherent et les donnees associees
852
	 *
853
	 *  @param	int		$rowid		Id of member to delete
854
	 *	@param	User		$user		User object
855
	 *	@param	int		$notrigger	1=Does not execute triggers, 0= execute triggers
856
	 *  @return	int					<0 if KO, 0=nothing to do, >0 if OK
857
	 */
858
	public function delete($rowid, $user, $notrigger = 0)
859
	{
860
		global $conf, $langs;
861
862
		$result = 0;
863
		$error=0;
864
		$errorflag=0;
865
866
		// Check parameters
867
		if (empty($rowid)) $rowid=$this->id;
868
869
		$this->db->begin();
870
871
		if (! $error && ! $notrigger)
872
		{
873
			// Call trigger
874
			$result=$this->call_trigger('MEMBER_DELETE', $user);
875
			if ($result < 0) $error++;
876
			// End call triggers
877
		}
878
879
		// Remove category
880
		$sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid;
881
		dol_syslog(get_class($this)."::delete", LOG_DEBUG);
882
		$resql=$this->db->query($sql);
883
		if (! $resql)
884
		{
885
			$error++;
886
			$this->error .= $this->db->lasterror();
887
			$errorflag=-1;
888
		}
889
890
		// Remove subscription
891
		if (! $error)
892
		{
893
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid;
894
			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
895
			$resql=$this->db->query($sql);
896
			if (! $resql)
897
			{
898
				$error++;
899
				$this->error .= $this->db->lasterror();
900
				$errorflag=-2;
901
			}
902
		}
903
904
		// Remove linked user
905
		if (! $error)
906
		{
907
			$ret=$this->setUserId(0);
908
			if ($ret < 0)
909
			{
910
				$error++;
911
				$this->error .= $this->db->lasterror();
912
				$errorflag=-3;
913
			}
914
		}
915
916
		// Removed extrafields
917
		if (! $error)
918
		{
919
			if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
920
			{
921
				$result=$this->deleteExtraFields();
922
				if ($result < 0)
923
				{
924
					$error++;
925
					$errorflag=-4;
926
					dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
927
				}
928
			}
929
		}
930
931
		// Remove adherent
932
		if (! $error)
933
		{
934
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid;
935
			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
936
			$resql=$this->db->query($sql);
937
			if (! $resql)
938
			{
939
				$error++;
940
				$this->error .= $this->db->lasterror();
941
				$errorflag=-5;
942
			}
943
		}
944
945
		if (! $error)
946
		{
947
			$this->db->commit();
948
			return 1;
949
		}
950
		else
951
		{
952
			$this->db->rollback();
953
			return $errorflag;
954
		}
955
	}
956
957
958
	/**
959
	 *    Change password of a user
960
	 *
961
	 *    @param	User	$user           Object user de l'utilisateur qui fait la modification
962
	 *    @param 	string	$password       New password (to generate if empty)
963
	 *    @param    int		$isencrypted    0 ou 1 si il faut crypter le mot de passe en base (0 par defaut)
964
	 *	  @param	int		$notrigger		1=Ne declenche pas les triggers
965
	 *    @param	int		$nosyncuser		Do not synchronize linked user
966
	 *    @return   string           		If OK return clear password, 0 if no change, < 0 if error
967
	 */
968
	public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
969
	{
970
		global $conf, $langs;
971
972
		$error=0;
973
974
		dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." isencrypted=".$isencrypted);
975
976
		// If new password not provided, we generate one
977
		if (! $password)
978
		{
979
			require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
980
			$password=getRandomPassword(false);
981
		}
982
983
		// Crypt password
984
		$password_crypted = dol_hash($password);
985
986
		$password_indatabase = '';
987
		if (! $isencrypted)
988
		{
989
			$password_indatabase = $password;
990
		}
991
992
		$this->db->begin();
993
994
		// Mise a jour
995
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
996
		$sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
997
		//if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
998
		if ($isencrypted)
999
		{
1000
			$sql.= ", pass = null";
1001
		}
1002
		else
1003
		{
1004
			$sql.= ", pass = '".$this->db->escape($password_indatabase)."'";
1005
		}
1006
		$sql.= " WHERE rowid = ".$this->id;
1007
1008
		//dol_syslog("Adherent::Password sql=hidden");
1009
		dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
1010
		$result = $this->db->query($sql);
1011
		if ($result)
1012
		{
1013
			$nbaffectedrows=$this->db->affected_rows($result);
1014
1015
			if ($nbaffectedrows)
1016
			{
1017
				$this->pass=$password;
1018
				$this->pass_indatabase=$password_indatabase;
1019
				$this->pass_indatabase_crypted=$password_crypted;
1020
1021
				if ($this->user_id && ! $nosyncuser)
1022
				{
1023
					require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1024
1025
					// This member is linked with a user, so we also update users informations
1026
					// if this is an update.
1027
					$luser=new User($this->db);
1028
					$result=$luser->fetch($this->user_id);
1029
1030
					if ($result >= 0)
1031
					{
1032
						$result=$luser->setPassword($user, $this->pass, 0, 0, 1);
1033
						if ($result < 0)
1034
						{
1035
							$this->error=$luser->error;
1036
							dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR);
1037
							$error++;
1038
						}
1039
					}
1040
					else
1041
					{
1042
						$this->error=$luser->error;
1043
						$error++;
1044
					}
1045
				}
1046
1047
				if (! $error && ! $notrigger)
1048
				{
1049
					// Call trigger
1050
					$result=$this->call_trigger('MEMBER_NEW_PASSWORD', $user);
1051
					if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1052
					// End call triggers
1053
				}
1054
1055
				$this->db->commit();
1056
				return $this->pass;
1057
			}
1058
			else
1059
			{
1060
				$this->db->rollback();
1061
				return 0;
1062
			}
1063
		}
1064
		else
1065
		{
1066
			$this->db->rollback();
1067
			dol_print_error($this->db);
1068
			return -1;
1069
		}
1070
	}
1071
1072
1073
	/**
1074
	 *    Set link to a user
1075
	 *
1076
	 *    @param     int	$userid        	Id of user to link to
1077
	 *    @return    int					1=OK, -1=KO
1078
	 */
1079
	public function setUserId($userid)
1080
	{
1081
		global $conf, $langs;
1082
1083
		$this->db->begin();
1084
1085
		// If user is linked to this member, remove old link to this member
1086
		$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
1087
		dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1088
		$resql = $this->db->query($sql);
1089
		if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -1; }
1090
1091
		// Set link to user
1092
		if ($userid > 0)
1093
		{
1094
			$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id;
1095
			$sql.= " WHERE rowid = ".$userid;
1096
			dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
1097
			$resql = $this->db->query($sql);
1098
			if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -2; }
1099
		}
1100
1101
		$this->db->commit();
1102
1103
		return 1;
1104
	}
1105
1106
1107
	/**
1108
	 *    Set link to a third party
1109
	 *
1110
	 *    @param     int	$thirdpartyid		Id of user to link to
1111
	 *    @return    int						1=OK, -1=KO
1112
	 */
1113
	public function setThirdPartyId($thirdpartyid)
1114
	{
1115
		global $conf, $langs;
1116
1117
		$this->db->begin();
1118
1119
		// Remove link to third party onto any other members
1120
		if ($thirdpartyid > 0)
1121
		{
1122
			$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
1123
			$sql.= " WHERE fk_soc = '".$thirdpartyid."'";
1124
			$sql.= " AND entity = ".$conf->entity;
1125
			dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1126
			$resql = $this->db->query($sql);
1127
		}
1128
1129
		// Add link to third party for current member
1130
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid>0 ? $thirdpartyid : 'null');
1131
		$sql.= " WHERE rowid = ".$this->id;
1132
1133
		dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
1134
		$resql = $this->db->query($sql);
1135
		if ($resql)
1136
		{
1137
			$this->db->commit();
1138
			return 1;
1139
		}
1140
		else
1141
		{
1142
			$this->error=$this->db->error();
1143
			$this->db->rollback();
1144
			return -1;
1145
		}
1146
	}
1147
1148
1149
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1150
	/**
1151
	 *	Method to load member from its login
1152
	 *
1153
	 *	@param	string	$login		login of member
1154
	 *	@return	void
1155
	 */
1156
	public function fetch_login($login)
1157
	{
1158
        // phpcs:enable
1159
		global $conf;
1160
1161
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1162
		$sql.= " WHERE login='".$this->db->escape($login)."'";
1163
		$sql.= " AND entity = ".$conf->entity;
1164
1165
		$resql=$this->db->query($sql);
1166
		if ($resql)
1167
		{
1168
			if ($this->db->num_rows($resql))
1169
			{
1170
				$obj = $this->db->fetch_object($resql);
1171
				$this->fetch($obj->rowid);
1172
			}
1173
		}
1174
		else
1175
		{
1176
			dol_print_error($this->db);
1177
		}
1178
	}
1179
1180
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1181
	/**
1182
	 *	Method to load member from its name
1183
	 *
1184
	 *	@param	string	$firstname	Firstname
1185
	 *	@param	string	$lastname	Lastname
1186
	 *	@return	void
1187
	 */
1188
	public function fetch_name($firstname, $lastname)
1189
	{
1190
        // phpcs:enable
1191
		global $conf;
1192
1193
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1194
		$sql.= " WHERE firstname='".$this->db->escape($firstname)."'";
1195
		$sql.= " AND lastname='".$this->db->escape($lastname)."'";
1196
		$sql.= " AND entity = ".$conf->entity;
1197
1198
		$resql=$this->db->query($sql);
1199
		if ($resql)
1200
		{
1201
			if ($this->db->num_rows($resql))
1202
			{
1203
				$obj = $this->db->fetch_object($resql);
1204
				$this->fetch($obj->rowid);
1205
			}
1206
		}
1207
		else
1208
		{
1209
			dol_print_error($this->db);
1210
		}
1211
	}
1212
1213
	/**
1214
	 *	Load member from database
1215
	 *
1216
	 *	@param	int		$rowid      			Id of object to load
1217
	 * 	@param	string	$ref					To load member from its ref
1218
	 * 	@param	int		$fk_soc					To load member from its link to third party
1219
	 * 	@param	string	$ref_ext				External reference
1220
	 *  @param	bool	$fetch_optionals		To load optionals (extrafields)
1221
	 *  @param	bool	$fetch_subscriptions	To load member subscriptions
1222
	 *	@return int								>0 if OK, 0 if not found, <0 if KO
1223
	 */
1224
	public function fetch($rowid, $ref = '', $fk_soc = '', $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
1225
	{
1226
		global $langs;
1227
1228
		$sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1229
		$sql.= " d.note_public,";
1230
		$sql.= " d.email, d.skype, d.twitter, d.facebook, d.linkedin, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1231
		$sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1232
		$sql.= " d.datec as datec,";
1233
		$sql.= " d.tms as datem,";
1234
		$sql.= " d.datefin as datefin,";
1235
		$sql.= " d.birth as birthday,";
1236
		$sql.= " d.datevalid as datev,";
1237
		$sql.= " d.country,";
1238
		$sql.= " d.state_id,";
1239
		$sql.= " d.model_pdf,";
1240
		$sql.= " c.rowid as country_id, c.code as country_code, c.label as country,";
1241
		$sql.= " dep.nom as state, dep.code_departement as state_code,";
1242
		$sql.= " t.libelle as type, t.subscription as subscription,";
1243
		$sql.= " u.rowid as user_id, u.login as user_login";
1244
		$sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
1245
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
1246
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
1247
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
1248
		$sql.= " WHERE d.fk_adherent_type = t.rowid";
1249
		if ($rowid) $sql.= " AND d.rowid=".$rowid;
1250
		elseif ($ref || $fk_soc) {
1251
			$sql.= " AND d.entity IN (".getEntity('adherent').")";
1252
			if ($ref) $sql.= " AND d.rowid='".$this->db->escape($ref)."'";
1253
			elseif ($fk_soc > 0) $sql.= " AND d.fk_soc=".$fk_soc;
1254
		}
1255
		elseif ($ref_ext)
1256
		{
1257
			$sql.= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
1258
		}
1259
1260
		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1261
		$resql=$this->db->query($sql);
1262
		if ($resql)
1263
		{
1264
			if ($this->db->num_rows($resql))
1265
			{
1266
				$obj = $this->db->fetch_object($resql);
1267
1268
				$this->entity			= $obj->entity;
1269
				$this->ref				= $obj->rowid;
1270
				$this->id				= $obj->rowid;
1271
				$this->ref_ext			= $obj->ref_ext;
1272
1273
				$this->civility_id      = $obj->civility_code;  // Bad. Kept for backard compatibility
1274
				$this->civility_code    = $obj->civility_code;
1275
				$this->civility	        = $obj->civility_code?($langs->trans("Civility".$obj->civility_code) != ("Civility".$obj->civility_code) ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code):'';
1276
1277
				$this->firstname		= $obj->firstname;
1278
				$this->lastname			= $obj->lastname;
1279
				$this->gender			= $obj->gender;
1280
				$this->login			= $obj->login;
1281
				$this->societe			= $obj->company;
1282
				$this->company			= $obj->company;
1283
				$this->socid			= $obj->fk_soc;
1284
				$this->fk_soc			= $obj->fk_soc;     // For backward comaptibility
1285
				$this->address			= $obj->address;
1286
				$this->zip				= $obj->zip;
1287
				$this->town				= $obj->town;
1288
1289
				$this->pass				= $obj->pass;
1290
				$this->pass_indatabase  = $obj->pass;
1291
				$this->pass_indatabase_crypted = $obj->pass_crypted;
1292
1293
				$this->state_id			= $obj->state_id;
1294
				$this->state_code		= $obj->state_id?$obj->state_code:'';
1295
				$this->state			= $obj->state_id?$obj->state:'';
1296
1297
				$this->country_id		= $obj->country_id;
1298
				$this->country_code		= $obj->country_code;
1299
				if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code)
1300
					$this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
1301
				else
1302
					$this->country=$obj->country;
1303
1304
				$this->phone			= $obj->phone;
1305
				$this->phone_perso		= $obj->phone_perso;
1306
				$this->phone_mobile		= $obj->phone_mobile;
1307
				$this->email			= $obj->email;
1308
1309
				$this->skype			= $obj->skype;
1310
				$this->twitter			= $obj->twitter;
1311
				$this->facebook			= $obj->facebook;
1312
				$this->linkedin			= $obj->linkedin;
1313
1314
				$this->photo			= $obj->photo;
1315
				$this->statut			= $obj->statut;
1316
				$this->public			= $obj->public;
1317
1318
				$this->datec			= $this->db->jdate($obj->datec);
1319
                $this->date_creation    = $this->db->jdate($obj->datec);
1320
				$this->datem			= $this->db->jdate($obj->datem);
1321
                $this->date_modification= $this->db->jdate($obj->datem);
1322
				$this->datefin			= $this->db->jdate($obj->datefin);
1323
				$this->datevalid		= $this->db->jdate($obj->datev);
1324
                $this->date_validation	= $this->db->jdate($obj->datev);
1325
				$this->birth			= $this->db->jdate($obj->birthday);
1326
1327
				$this->note_private		= $obj->note_private;
1328
				$this->note_public		= $obj->note_public;
1329
				$this->morphy			= $obj->morphy;
1330
1331
				$this->typeid			= $obj->fk_adherent_type;
1332
				$this->type				= $obj->type;
1333
				$this->need_subscription 	= $obj->subscription;
1334
1335
				$this->user_id			= $obj->user_id;
1336
				$this->user_login		= $obj->user_login;
1337
1338
				$this->model_pdf        = $obj->model_pdf;
1339
1340
				// Retreive all extrafield
1341
				// fetch optionals attributes and labels
1342
				if ($fetch_optionals) {
1343
					$this->fetch_optionals();
1344
				}
1345
1346
				// Load other properties
1347
				if ($fetch_subscriptions) {
1348
					$result=$this->fetch_subscriptions();
1349
				}
1350
1351
				return $this->id;
1352
			}
1353
			else
1354
			{
1355
				return 0;
1356
			}
1357
		}
1358
		else
1359
		{
1360
			$this->error=$this->db->lasterror();
1361
			return -1;
1362
		}
1363
	}
1364
1365
1366
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1367
	/**
1368
	 *	Function to get member subscriptions data
1369
	 *				first_subscription_date, first_subscription_date_start, first_subscription_date_end, first_subscription_amount
1370
	 *				last_subscription_date, last_subscription_date_start, last_subscription_date_end, last_subscription_amount
1371
	 *
1372
	 *	@return		int			<0 si KO, >0 si OK
1373
	 */
1374
	public function fetch_subscriptions()
1375
	{
1376
        // phpcs:enable
1377
		global $langs;
1378
1379
		require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1380
1381
		$sql = "SELECT c.rowid, c.fk_adherent, c.subscription, c.note, c.fk_bank,";
1382
		$sql.= " c.tms as datem,";
1383
		$sql.= " c.datec as datec,";
1384
		$sql.= " c.dateadh as dateh,";
1385
		$sql.= " c.datef as datef";
1386
		$sql.= " FROM ".MAIN_DB_PREFIX."subscription as c";
1387
		$sql.= " WHERE c.fk_adherent = ".$this->id;
1388
		$sql.= " ORDER BY c.dateadh";
1389
		dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
1390
1391
		$resql=$this->db->query($sql);
1392
		if ($resql)
1393
		{
1394
			$this->subscriptions=array();
1395
1396
			$i=0;
1397
			while ($obj = $this->db->fetch_object($resql))
1398
			{
1399
				if ($i==0)
1400
				{
1401
					$this->first_subscription_date=$this->db->jdate($obj->datec);
1402
					$this->first_subscription_date_start=$this->db->jdate($obj->dateh);
1403
					$this->first_subscription_date_end=$this->db->jdate($obj->datef);
1404
					$this->first_subscription_amount=$obj->subscription;
1405
				}
1406
				$this->last_subscription_date=$this->db->jdate($obj->datec);
1407
				$this->last_subscription_date_start=$this->db->jdate($obj->datef);
1408
				$this->last_subscription_date_end=$this->db->jdate($obj->datef);
1409
				$this->last_subscription_amount=$obj->subscription;
1410
1411
				$subscription=new Subscription($this->db);
1412
				$subscription->id=$obj->rowid;
1413
				$subscription->fk_adherent=$obj->fk_adherent;
1414
				$subscription->amount=$obj->subscription;
1415
				$subscription->note=$obj->note;
1416
				$subscription->fk_bank=$obj->fk_bank;
1417
				$subscription->datem=$this->db->jdate($obj->datem);
1418
				$subscription->datec=$this->db->jdate($obj->datec);
1419
				$subscription->dateh=$this->db->jdate($obj->dateh);
1420
				$subscription->datef=$this->db->jdate($obj->datef);
1421
1422
				$this->subscriptions[]=$subscription;
1423
1424
				$i++;
1425
			}
1426
			return 1;
1427
		}
1428
		else
1429
		{
1430
			$this->error=$this->db->error().' sql='.$sql;
1431
			return -1;
1432
		}
1433
	}
1434
1435
1436
	/**
1437
	 *	Insert subscription into database and eventually add links to banks, mailman, etc...
1438
	 *
1439
	 *	@param	int	        $date        		Date of effect of subscription
1440
	 *	@param	double		$amount     		Amount of subscription (0 accepted for some members)
1441
	 *	@param	int			$accountid			Id bank account
1442
	 *	@param	string		$operation			Type of payment (if Id bank account provided). Example: 'CB', ...
1443
	 *	@param	string		$label				Label operation (if Id bank account provided)
1444
	 *	@param	string		$num_chq			Numero cheque (if Id bank account provided)
1445
	 *	@param	string		$emetteur_nom		Name of cheque writer
1446
	 *	@param	string		$emetteur_banque	Name of bank of cheque
1447
	 *	@param	int     	$datesubend			Date end subscription
1448
	 *	@return int         					rowid of record added, <0 if KO
1449
	 */
1450
	public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0)
1451
	{
1452
		global $conf,$langs,$user;
1453
1454
		require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1455
1456
		$error=0;
1457
1458
		// Clean parameters
1459
		if (! $amount) $amount=0;
1460
1461
		$this->db->begin();
1462
1463
		if ($datesubend)
1464
		{
1465
			$datefin=$datesubend;
1466
		}
1467
		else
1468
		{
1469
			// If no end date, end date = date + 1 year - 1 day
1470
			$datefin = dol_time_plus_duree($date, 1, 'y');
1471
			$datefin = dol_time_plus_duree($datefin, -1, 'd');
1472
		}
1473
1474
		// Create subscription
1475
		$subscription=new Subscription($this->db);
1476
		$subscription->fk_adherent=$this->id;
1477
		$subscription->dateh=$date;		// Date of new subscription
1478
		$subscription->datef=$datefin;	// End data of new subscription
1479
		$subscription->amount=$amount;
1480
		$subscription->note=$label;		// deprecated
1 ignored issue
show
Deprecated Code introduced by
The property CommonObject::$note has been deprecated. ( Ignorable by Annotation )

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

1480
		/** @scrutinizer ignore-deprecated */ $subscription->note=$label;		// deprecated
Loading history...
1481
		$subscription->note_public=$label;
1482
1483
		$rowid=$subscription->create($user);
1484
		if ($rowid > 0)
1485
		{
1486
			// Update denormalized subscription end date (read database subscription to find values)
1487
			// This will also update this->datefin
1488
			$result=$this->update_end_date($user);
1489
			if ($result > 0)
1490
			{
1491
				// Change properties of object (used by triggers)
1492
				$this->last_subscription_date=dol_now();
1493
				$this->last_subscription_date_start=$date;
1494
				$this->last_subscription_date_end=$datefin;
1495
				$this->last_subscription_amount=$amount;
1496
			}
1497
1498
			if (! $error)
1499
			{
1500
				$this->db->commit();
1501
				return $rowid;
1502
			}
1503
			else
1504
			{
1505
				$this->db->rollback();
1506
				return -2;
1507
			}
1508
		}
1509
		else
1510
		{
1511
			$this->error=$subscription->error;
1512
			$this->errors=$subscription->errors;
1513
			$this->db->rollback();
1514
			return -1;
1515
		}
1516
	}
1517
1518
1519
	/**
1520
	 *	Do complementary actions after subscription recording.
1521
	 *
1522
	 *	@param	int			$subscriptionid			Id of created subscription
1523
	 *  @param	string		$option					Which action ('bankdirect', 'bankviainvoice', 'invoiceonly', ...)
1524
	 *	@param	int			$accountid				Id bank account
1525
	 *	@param	int			$datesubscription		Date of subscription
1526
	 *	@param	int			$paymentdate			Date of payment
1527
	 *	@param	string		$operation				Code of type of operation (if Id bank account provided). Example 'CB', ...
1528
	 *	@param	string		$label					Label operation (if Id bank account provided)
1529
	 *	@param	double		$amount     			Amount of subscription (0 accepted for some members)
1530
	 *	@param	string		$num_chq				Numero cheque (if Id bank account provided)
1531
	 *	@param	string		$emetteur_nom			Name of cheque writer
1532
	 *	@param	string		$emetteur_banque		Name of bank of cheque
1533
	 *  @param	string		$autocreatethirdparty	Auto create new thirdparty if member not yet linked to a thirdparty and we request an option that generate invoice.
1534
	 *	@return int									<0 if KO, >0 if OK
1535
	 */
1536
	public function subscriptionComplementaryActions($subscriptionid, $option, $accountid, $datesubscription, $paymentdate, $operation, $label, $amount, $num_chq, $emetteur_nom = '', $emetteur_banque = '', $autocreatethirdparty = 0)
1537
	{
1538
		global $conf, $langs, $user, $mysoc;
1539
1540
		$error = 0;
1541
1542
		$this->invoice = null;	// This will contains invoice if an invoice is created
1543
1544
		dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".$paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
1545
1546
		// Insert into bank account directlty (if option choosed for) + link to llx_subscription if option is 'bankdirect'
1547
		if ($option == 'bankdirect' && $accountid)
1548
		{
1549
			require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1550
1551
			$acct=new Account($this->db);
1552
			$result=$acct->fetch($accountid);
1553
1554
			$dateop=$paymentdate;
1555
1556
			$insertid=$acct->addline($dateop, $operation, $label, $amount, $num_chq, '', $user, $emetteur_nom, $emetteur_banque);
1557
			if ($insertid > 0)
1558
			{
1559
				$inserturlid=$acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullname($langs), 'member');
1560
				if ($inserturlid > 0)
1561
				{
1562
					// Update table subscription
1563
					$sql ="UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".$insertid;
1564
					$sql.=" WHERE rowid=".$subscriptionid;
1565
1566
					dol_syslog("subscription::subscription", LOG_DEBUG);
1567
					$resql = $this->db->query($sql);
1568
					if (! $resql)
1569
					{
1570
						$error++;
1571
						$this->error=$this->db->lasterror();
1572
						$this->errors[]=$this->error;
1573
					}
1574
				}
1575
				else
1576
				{
1577
					$error++;
1578
					$this->error=$acct->error;
1579
					$this->errors=$acct->errors;
1580
				}
1581
			}
1582
			else
1583
			{
1584
				$error++;
1585
				$this->error=$acct->error;
1586
				$this->errors=$acct->errors;
1587
			}
1588
		}
1589
1590
		// If option choosed, we create invoice
1591
		if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly')
1592
		{
1593
			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1594
			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
1595
1596
			$invoice=new Facture($this->db);
1597
			$customer=new Societe($this->db);
1598
1599
			if (! $error)
1600
			{
1601
				if (! ($this->fk_soc > 0))	// If not yet linked to a company
1602
				{
1603
					if ($autocreatethirdparty)
1604
					{
1605
						// Create a linked thirdparty to member
1606
						$companyalias='';
1607
						$fullname = $this->getFullName($langs);
1608
1609
						if ($this->morphy == 'mor')
1610
						{
1611
							$companyname=$this->societe;
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

1611
							$companyname=/** @scrutinizer ignore-deprecated */ $this->societe;
Loading history...
1612
							if (! empty($fullname)) $companyalias=$fullname;
1613
						}
1614
						else
1615
						{
1616
							$companyname=$fullname;
1617
							if (! empty($this->societe)) $companyalias=$this->societe;
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

1617
							if (! empty(/** @scrutinizer ignore-deprecated */ $this->societe)) $companyalias=$this->societe;
Loading history...
1618
						}
1619
1620
						$result=$customer->create_from_member($this, $companyname, $companyalias);
1621
						if ($result < 0)
1622
						{
1623
							$this->error = $customer->error;
1624
							$this->errors = $customer->errors;
1625
							$error++;
1626
						}
1627
						else
1628
						{
1629
							$this->fk_soc = $result;
1630
						}
1631
					}
1632
					else
1633
					{
1634
						 $langs->load("errors");
1635
						 $this->error=$langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1636
						 $this->errors[]=$this->error;
1637
						 $error++;
1638
					}
1639
				}
1640
			}
1641
			if (! $error)
1642
			{
1643
				$result=$customer->fetch($this->fk_soc);
1644
				if ($result <= 0)
1645
				{
1646
					$this->error=$customer->error;
1647
					$this->errors=$customer->errors;
1648
					$error++;
1649
				}
1650
			}
1651
1652
			if (! $error)
1653
			{
1654
				// Create draft invoice
1655
				$invoice->type=Facture::TYPE_STANDARD;
1656
				$invoice->cond_reglement_id=$customer->cond_reglement_id;
1657
				if (empty($invoice->cond_reglement_id))
1658
				{
1659
					$paymenttermstatic=new PaymentTerm($this->db);
1660
					$invoice->cond_reglement_id=$paymenttermstatic->getDefaultId();
1661
					if (empty($invoice->cond_reglement_id))
1662
					{
1663
						$error++;
1664
						$this->error='ErrorNoPaymentTermRECEPFound';
1665
						$this->errors[]=$this->error;
1666
					}
1667
				}
1668
				$invoice->socid=$this->fk_soc;
1669
				$invoice->date=$datesubscription;
1670
1671
				// Possibility to add external linked objects with hooks
1672
				$invoice->linked_objects['subscription'] = $subscriptionid;
1673
				if (! empty($_POST['other_linked_objects']) && is_array($_POST['other_linked_objects']))
1674
				{
1675
					$invoice->linked_objects = array_merge($invoice->linked_objects, $_POST['other_linked_objects']);
1676
				}
1677
1678
				$result=$invoice->create($user);
1679
				if ($result <= 0)
1680
				{
1681
					$this->error=$invoice->error;
1682
					$this->errors=$invoice->errors;
1683
					$error++;
1684
				}
1685
				else
1686
				{
1687
					$this->invoice = $invoice;
1688
				}
1689
			}
1690
1691
			if (! $error)
1692
			{
1693
				// Add line to draft invoice
1694
				$idprodsubscription=0;
1695
				if (! empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) && (! empty($conf->product->enabled) || ! empty($conf->service->enabled))) $idprodsubscription = $conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS;
1696
1697
				$vattouse=0;
1698
				if (isset($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) && $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS == 'defaultforfoundationcountry')
1699
				{
1700
					$vattouse=get_default_tva($mysoc, $mysoc, $idprodsubscription);
1701
				}
1702
				//print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1703
				$result=$invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, '', 'TTC', $amount, 1);
1704
				if ($result <= 0)
1705
				{
1706
					$this->error=$invoice->error;
1707
					$this->errors=$invoice->errors;
1708
					$error++;
1709
				}
1710
			}
1711
1712
			if (! $error)
1713
			{
1714
				// Validate invoice
1715
				$result=$invoice->validate($user);
1716
				if ($result <= 0)
1717
				{
1718
					$this->error=$invoice->error;
1719
					$this->errors=$invoice->errors;
1720
					$error++;
1721
				}
1722
			}
1723
1724
			if (! $error)
1725
			{
1726
				// TODO Link invoice with subscription ?
1727
			}
1728
1729
			// Add payment onto invoice
1730
			if (! $error && $option == 'bankviainvoice' && $accountid)
1731
			{
1732
				require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1733
				require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1734
				require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
1735
1736
				$amounts = array();
1737
				$amounts[$invoice->id] = price2num($amount);
1738
1739
				$paiement = new Paiement($this->db);
1740
				$paiement->datepaye     = $paymentdate;
1741
				$paiement->amounts      = $amounts;
1742
				$paiement->paiementid   = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
1743
				$paiement->num_paiement = $num_chq;
1 ignored issue
show
Deprecated Code introduced by
The property Paiement::$num_paiement has been deprecated. ( Ignorable by Annotation )

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

1743
				/** @scrutinizer ignore-deprecated */ $paiement->num_paiement = $num_chq;
Loading history...
1744
				$paiement->note         = $label;
1 ignored issue
show
Deprecated Code introduced by
The property CommonObject::$note has been deprecated. ( Ignorable by Annotation )

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

1744
				/** @scrutinizer ignore-deprecated */ $paiement->note         = $label;
Loading history...
1745
				$paiement->note_public  = $label;
1746
1747
				if (! $error)
1748
				{
1749
					// Create payment line for invoice
1750
					$paiement_id = $paiement->create($user);
1751
					if (! $paiement_id > 0)
1752
					{
1753
						$this->error=$paiement->error;
1754
						$this->errors=$paiement->errors;
1755
						$error++;
1756
					}
1757
				}
1758
1759
				if (! $error)
1760
				{
1761
					// Add transaction into bank account
1762
					$bank_line_id=$paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
1763
					if (! ($bank_line_id > 0))
1764
					{
1765
						$this->error=$paiement->error;
1766
						$this->errors=$paiement->errors;
1767
						$error++;
1768
					}
1769
				}
1770
1771
				if (! $error && !empty($bank_line_id))
1772
				{
1773
					// Update fk_bank into subscription table
1774
					$sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.$bank_line_id;
1775
					$sql.= ' WHERE rowid='.$subscriptionid;
1776
1777
					$result = $this->db->query($sql);
1778
					if (! $result)
1779
					{
1780
						$error++;
1781
					}
1782
				}
1783
1784
				if (! $error)
1785
				{
1786
					// Set invoice as paid
1787
					$invoice->set_paid($user);
1788
				}
1789
			}
1790
1791
			if (! $error)
1792
			{
1793
				// Define output language
1794
				$outputlangs = $langs;
1795
				$newlang = '';
1796
				$lang_id=GETPOST('lang_id');
1797
				if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($lang_id))
1798
					$newlang = $lang_id;
1799
				if ($conf->global->MAIN_MULTILANGS && empty($newlang))
1800
					$newlang = $customer->default_lang;
1801
				if (! empty($newlang)) {
1802
					$outputlangs = new Translate("", $conf);
1803
					$outputlangs->setDefaultLang($newlang);
1804
				}
1805
				// Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
1806
				//if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
1807
1808
				$invoice->generateDocument($invoice->modelpdf, $outputlangs);
1809
			}
1810
		}
1811
1812
		if ($error)
1813
		{
1814
			return -1;
1815
		}
1816
		else
1817
		{
1818
			return 1;
1819
		}
1820
	}
1821
1822
1823
	/**
1824
	 *		Function that validate a member
1825
	 *
1826
	 *		@param	User	$user		user adherent qui valide
1827
	 *		@return	int					<0 if KO, 0 if nothing done, >0 if OK
1828
	 */
1829
	public function validate($user)
1830
	{
1831
		global $langs,$conf;
1832
1833
		$error=0;
1834
		$now=dol_now();
1835
1836
		// Check parameters
1837
		if ($this->statut == 1)
1838
		{
1839
			dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
1840
			return 0;
1841
		}
1842
1843
		$this->db->begin();
1844
1845
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1846
		$sql.= " statut = 1";
1847
		$sql.= ", datevalid = '".$this->db->idate($now)."'";
1848
		$sql.= ", fk_user_valid=".$user->id;
1849
		$sql.= " WHERE rowid = ".$this->id;
1850
1851
		dol_syslog(get_class($this)."::validate", LOG_DEBUG);
1852
		$result = $this->db->query($sql);
1853
		if ($result)
1854
		{
1855
			$this->statut=1;
1856
1857
			// Call trigger
1858
			$result=$this->call_trigger('MEMBER_VALIDATE', $user);
1859
			if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1860
			// End call triggers
1861
1862
			$this->datevalid = $now;
1863
1864
			$this->db->commit();
1865
			return 1;
1866
		}
1867
		else
1868
		{
1869
			$this->error=$this->db->error();
1870
			$this->db->rollback();
1871
			return -1;
1872
		}
1873
	}
1874
1875
1876
	/**
1877
	 *		Fonction qui resilie un adherent
1878
	 *
1879
	 *		@param	User	$user		User making change
1880
	 *		@return	int					<0 if KO, >0 if OK
1881
	 */
1882
	public function resiliate($user)
1883
	{
1884
		global $langs,$conf;
1885
1886
		$error=0;
1887
1888
		// Check parameters
1889
		if ($this->statut == 0)
1890
		{
1891
			dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
1892
			return 0;
1893
		}
1894
1895
		$this->db->begin();
1896
1897
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1898
		$sql.= " statut = 0";
1899
		$sql.= ", fk_user_valid=".$user->id;
1900
		$sql.= " WHERE rowid = ".$this->id;
1901
1902
		$result = $this->db->query($sql);
1903
		if ($result)
1904
		{
1905
			$this->statut=0;
1906
1907
			// Call trigger
1908
			$result=$this->call_trigger('MEMBER_RESILIATE', $user);
1909
			if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1910
			// End call triggers
1911
1912
			$this->db->commit();
1913
			return 1;
1914
		}
1915
		else
1916
		{
1917
			$this->error=$this->db->error();
1918
			$this->db->rollback();
1919
			return -1;
1920
		}
1921
	}
1922
1923
1924
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1925
	/**
1926
	 *  Function to add member into external tools mailing-list, spip, etc.
1927
	 *
1928
	 *  @return		int		<0 if KO, >0 if OK
1929
	 */
1930
	public function add_to_abo()
1931
	{
1932
        // phpcs:enable
1933
		global $conf,$langs;
1934
1935
		include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
1936
		$mailmanspip=new MailmanSpip($this->db);
1937
1938
		$err=0;
1939
1940
		// mailman
1941
		if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled))
1942
		{
1943
			$result=$mailmanspip->add_to_mailman($this);
1944
1945
			if ($result < 0)
1946
			{
1947
				if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
1948
				$err+=1;
1949
			}
1950
			foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail)
1951
			{
1952
				$langs->load("errors");
1953
				$this->errors[]=$langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
1954
			}
1955
			foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail)
1956
			{
1957
				$langs->load("mailmanspip");
1958
				$this->mesgs[]=$langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
1959
			}
1960
		}
1961
1962
		// spip
1963
		if (! empty($conf->global->ADHERENT_USE_SPIP) && ! empty($conf->mailmanspip->enabled))
1964
		{
1965
			$result=$mailmanspip->add_to_spip($this);
1966
			if ($result < 0)
1967
			{
1968
				$this->errors[]=$mailmanspip->error;
1969
				$err+=1;
1970
			}
1971
		}
1972
		if ($err)
1973
		{
1974
			return -$err;
1975
		}
1976
		else
1977
		{
1978
			return 1;
1979
		}
1980
	}
1981
1982
1983
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1984
	/**
1985
	 *  Function to delete a member from external tools like mailing-list, spip, etc.
1986
	 *
1987
	 *  @return     int     <0 if KO, >0 if OK
1988
	 */
1989
	public function del_to_abo()
1990
	{
1991
        // phpcs:enable
1992
		global $conf,$langs;
1993
1994
		include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
1995
		$mailmanspip=new MailmanSpip($this->db);
1996
1997
		$err=0;
1998
1999
		// mailman
2000
		if (! empty($conf->global->ADHERENT_USE_MAILMAN))
2001
		{
2002
			$result=$mailmanspip->del_to_mailman($this);
2003
			if ($result < 0)
2004
			{
2005
				if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
2006
				$err+=1;
2007
			}
2008
2009
			foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail)
2010
			{
2011
				$langs->load("errors");
2012
				$this->errors[]=$langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
2013
			}
2014
			foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail)
2015
			{
2016
				$langs->load("mailmanspip");
2017
				$this->mesgs[]=$langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
2018
			}
2019
		}
2020
2021
		if ($conf->global->ADHERENT_USE_SPIP && ! empty($conf->mailmanspip->enabled))
2022
		{
2023
			$result=$mailmanspip->del_to_spip($this);
2024
			if ($result < 0)
2025
			{
2026
				$this->errors[]=$mailmanspip->error;
2027
				$err+=1;
2028
			}
2029
		}
2030
		if ($err)
2031
		{
2032
			// error
2033
			return -$err;
2034
		}
2035
		else
2036
		{
2037
			return 1;
2038
		}
2039
	}
2040
2041
2042
	/**
2043
	 *    Return civility label of a member
2044
	 *
2045
	 *    @return   string              	Translated name of civility (translated with transnoentitiesnoconv)
2046
	 */
2047
	public function getCivilityLabel()
2048
	{
2049
		global $langs;
2050
		$langs->load("dict");
2051
2052
		$code=(empty($this->civility_id)?'':$this->civility_id);
2053
		if (empty($code)) return '';
2054
		return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
2055
	}
2056
2057
	/**
2058
	 *  Return clicable name (with picto eventually)
2059
	 *
2060
	 *	@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)
2061
	 *	@param	int		$maxlen						length max label
2062
	 *	@param	string	$option						Page for link ('card', 'category', 'subscription', ...)
2063
	 *  @param  string  $mode           			''=Show firstname+lastname as label (using default order), 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref
2064
	 *  @param  string  $morecss        			Add more css on link
2065
	 *  @param  int     $save_lastsearch_value    	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
2066
	 *	@return	string								Chaine avec URL
2067
	 */
2068
	public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1)
2069
	{
2070
		global $conf, $langs;
2071
2072
		if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
2073
2074
		$notooltip=0;
2075
2076
		$result=''; $label='';
2077
		$link=''; $linkstart=''; $linkend='';
2078
2079
		if (! empty($this->photo))
2080
		{
2081
			$label.= '<div class="photointooltip">';
2082
			$label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1);
2083
			$label.= '</div><div style="clear: both;"></div>';
2084
		}
2085
2086
		$label.= '<div class="centpercent">';
2087
		$label.= '<u>' . $langs->trans("Member") . '</u>';
2088
		if (! empty($this->ref))
2089
			$label.= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
2090
		if (! empty($this->firstname) || ! empty($this->lastname))
2091
			$label.= '<br><b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs);
2092
		if (! empty($this->company))
2093
			$label.= '<br><b>' . $langs->trans('Company') . ':</b> ' . $this->company;
2094
		$label.='</div>';
2095
2096
		$url = DOL_URL_ROOT.'/adherents/card.php?rowid='.$this->id;
2097
		if ($option == 'subscription')
2098
		{
2099
			$url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.$this->id;
2100
		}
2101
2102
		if ($option != 'nolink')
2103
		{
2104
			// Add param to save lastsearch_values or not
2105
			$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
2106
			if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
2107
			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
2108
		}
2109
2110
		$link = '<a href="'.$url.'"';
2111
		$linkclose="";
2112
		if (empty($notooltip))
1 ignored issue
show
introduced by
The condition empty($notooltip) is always true.
Loading history...
2113
		{
2114
			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
2115
			{
2116
				$langs->load("users");
2117
				$label=$langs->trans("ShowUser");
2118
				$linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
2119
			}
2120
			$linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
2121
			$linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
2122
		}
2123
2124
		$link.=$linkclose.'>';
2125
		$linkend='</a>';
2126
2127
		$result.=$link;
2128
		if ($withpictoimg) $result.='<div class="inline-block nopadding valignmiddle">';
2129
		if ($withpictoimg)
2130
		{
2131
			$paddafterimage='';
2132
			if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"';
2133
			// Only picto
2134
			if ($withpictoimg > 0) $picto='<span class="nopadding'.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</span>';
2135
			// Picto must be a photo
2136
			else $picto='<span class="nopadding'.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</span>';
2137
			$result.=$picto;
2138
		}
2139
		if ($withpictoimg > -2 && $withpictoimg != 2)
2140
		{
2141
			if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<span class="nopadding valignmiddle'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' usertext'.$morecss:'').'">';
2142
			if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen);
2143
			elseif ($mode == 'ref') $result.=$this->id;
2144
			else $result.=$this->getFullName($langs, '', ($mode == 'firstname' ? 2 : -1), $maxlen);
2145
			if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</span>';
2146
		}
2147
		if ($withpictoimg) $result.='</div>';
2148
		$result.=$linkend;
2149
2150
		return $result;
2151
	}
2152
2153
	/**
2154
	 *  Retourne le libelle du statut d'un adherent (brouillon, valide, resilie)
2155
	 *
2156
	 *  @param	int		$mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
2157
	 *  @return string				Label
2158
	 */
2159
	public function getLibStatut($mode = 0)
2160
	{
2161
		return $this->LibStatut($this->statut, $this->need_subscription, $this->datefin, $mode);
2162
	}
2163
2164
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2165
	/**
2166
	 *  Renvoi le libelle d'un statut donne
2167
	 *
2168
	 *  @param	int			$statut      			Id statut
2169
	 *	@param	int			$need_subscription		1 if member type need subscription, 0 otherwise
2170
	 *	@param	int     	$date_end_subscription	Date fin adhesion
2171
	 *  @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
2172
	 *  @return string      						Label
2173
	 */
2174
	public function LibStatut($statut, $need_subscription, $date_end_subscription, $mode = 0)
2175
	{
2176
        // phpcs:enable
2177
		global $langs;
2178
		$langs->load("members");
2179
		if ($mode == 0)
2180
		{
2181
			if ($statut == -1) return $langs->trans("MemberStatusDraft");
2182
			elseif ($statut >= 1) {
2183
				if (! $date_end_subscription)            return $langs->trans("MemberStatusActive");
2184
				elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate");
2185
				else                                     return $langs->trans("MemberStatusPaid");
2186
			}
2187
			elseif ($statut == 0)  return $langs->trans("MemberStatusResiliated");
2188
		}
2189
		elseif ($mode == 1)
2190
		{
2191
			if ($statut == -1) return $langs->trans("MemberStatusDraftShort");
2192
			elseif ($statut >= 1) {
2193
				if (! $date_end_subscription)            return $langs->trans("MemberStatusActiveShort");
2194
				elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLateShort");
2195
				else                                     return $langs->trans("MemberStatusPaidShort");
2196
			}
2197
			elseif ($statut == 0)  return $langs->trans("MemberStatusResiliatedShort");
2198
		}
2199
		elseif ($mode == 2)
2200
		{
2201
			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'), 'statut0').' '.$langs->trans("MemberStatusDraftShort");
2202
			elseif ($statut >= 1) {
2203
				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'), 'statut1').' '.$langs->trans("MemberStatusActiveShort");
2204
				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'), 'statut3').' '.$langs->trans("MemberStatusActiveLateShort");
2205
				else                                     return img_picto($langs->trans('MemberStatusPaid'), 'statut4').' '.$langs->trans("MemberStatusPaidShort");
2206
			}
2207
			elseif ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'), 'statut5').' '.$langs->trans("MemberStatusResiliatedShort");
2208
		}
2209
		elseif ($mode == 3)
2210
		{
2211
			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'), 'statut0');
2212
			elseif ($statut >= 1) {
2213
				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'), 'statut1');
2214
				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'), 'statut3');
2215
				else                                     return img_picto($langs->trans('MemberStatusPaid'), 'statut4');
2216
			}
2217
			elseif ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'), 'statut5');
2218
		}
2219
		elseif ($mode == 4)
2220
		{
2221
			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'), 'statut0').' '.$langs->trans("MemberStatusDraft");
2222
			elseif ($statut >= 1) {
2223
				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'), 'statut1').' '.$langs->trans("MemberStatusActive");
2224
				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'), 'statut3').' '.$langs->trans("MemberStatusActiveLate");
2225
				else                                     return img_picto($langs->trans('MemberStatusPaid'), 'statut4').' '.$langs->trans("MemberStatusPaid");
2226
			}
2227
			if ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'), 'statut5').' '.$langs->trans("MemberStatusResiliated");
2228
		}
2229
		elseif ($mode == 5)
2230
		{
2231
		    if ($statut == -1) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusDraftShort").'</span> '.img_picto($langs->trans('MemberStatusDraft'), 'statut0');
2232
			elseif ($statut >= 1) {
2233
				if (! $date_end_subscription)            return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveShort").' </span>'.img_picto($langs->trans('MemberStatusActive'), 'statut1');
2234
				elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLateShort").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'), 'statut3');
2235
				else                                     return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaidShort").' </span>'.img_picto($langs->trans('MemberStatusPaid'), 'statut4');
2236
			}
2237
			if ($statut == 0)  return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'), 'statut5');
2238
		}
2239
		elseif ($mode == 6)
2240
		{
2241
		    if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'), 'statut0');
2242
			if ($statut >= 1) {
2243
				if (! $date_end_subscription)            return $langs->trans("MemberStatusActive").' '.img_picto($langs->trans('MemberStatusActive'), 'statut1');
2244
				elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate").' '.img_picto($langs->trans('MemberStatusActiveLate'), 'statut3');
2245
				else                                     return $langs->trans("MemberStatusPaid").' '.img_picto($langs->trans('MemberStatusPaid'), 'statut4');
2246
			}
2247
			if ($statut == 0)  return $langs->trans("MemberStatusResiliated").' '.img_picto($langs->trans('MemberStatusResiliated'), 'statut5');
2248
		}
2249
	}
2250
2251
2252
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2253
	/**
2254
	 *      Charge indicateurs this->nb de tableau de bord
2255
	 *
2256
	 *      @return     int         <0 if KO, >0 if OK
2257
	 */
2258
	public function load_state_board()
2259
	{
2260
        // phpcs:enable
2261
		global $conf;
2262
2263
		$this->nb = array();
2264
2265
		$sql = "SELECT count(a.rowid) as nb";
2266
		$sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
2267
		$sql.= " WHERE a.statut > 0";
2268
		$sql.= " AND a.entity IN (".getEntity('adherent').")";
2269
2270
		$resql=$this->db->query($sql);
2271
		if ($resql)
2272
		{
2273
			while ($obj=$this->db->fetch_object($resql))
2274
			{
2275
				$this->nb["members"]=$obj->nb;
2276
			}
2277
			$this->db->free($resql);
2278
			return 1;
2279
		}
2280
		else
2281
		{
2282
			dol_print_error($this->db);
2283
			$this->error=$this->db->error();
2284
			return -1;
2285
		}
2286
	}
2287
2288
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2289
	/**
2290
	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
2291
	 *
2292
	 *      @param	User	$user   		Objet user
2293
	 *      @return WorkboardResponse|int 	<0 if KO, WorkboardResponse if OK
2294
	 */
2295
	public function load_board($user)
2296
	{
2297
        // phpcs:enable
2298
		global $conf, $langs;
2299
2300
		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
1 ignored issue
show
Deprecated Code introduced by
The property User::$societe_id has been deprecated. ( Ignorable by Annotation )

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

2300
		if (/** @scrutinizer ignore-deprecated */ $user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
Loading history...
2301
2302
		$now=dol_now();
2303
2304
		$sql = "SELECT a.rowid, a.datefin, a.statut";
2305
		$sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
2306
		$sql.= " WHERE a.statut = 1";
2307
		$sql.= " AND a.entity IN (".getEntity('adherent').")";
2308
		$sql.= " AND (a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."')";
2309
2310
		$resql=$this->db->query($sql);
2311
		if ($resql)
2312
		{
2313
			$langs->load("members");
2314
2315
			$response = new WorkboardResponse();
2316
			$response->warning_delay=$conf->adherent->subscription->warning_delay/60/60/24;
2317
			$response->label=$langs->trans("MembersWithSubscriptionToReceive");
2318
			$response->url=DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut=1&amp;filter=outofdate';
2319
			$response->img=img_object('', "user");
2320
2321
			$adherentstatic = new Adherent($this->db);
2322
2323
			while ($obj=$this->db->fetch_object($resql))
2324
			{
2325
				$response->nbtodo++;
2326
2327
				$adherentstatic->datefin = $this->db->jdate($obj->datefin);
2328
				$adherentstatic->statut = $obj->statut;
2329
2330
				if ($adherentstatic->hasDelay()) {
2331
					$response->nbtodolate++;
2332
				}
2333
			}
2334
2335
			return $response;
2336
		}
2337
		else
2338
		{
2339
			dol_print_error($this->db);
2340
			$this->error=$this->db->error();
2341
			return -1;
2342
		}
2343
	}
2344
2345
2346
	/**
2347
	 *  Create a document onto disk according to template module.
2348
	 *
2349
	 *  @param	    string		$modele			Force template to use ('' to not force)
2350
	 *  @param		Translate	$outputlangs	objet lang a utiliser pour traduction
2351
	 *  @param      int			$hidedetails    Hide details of lines
2352
	 *  @param      int			$hidedesc       Hide description
2353
	 *  @param      int			$hideref        Hide ref
2354
         *  @param   null|array  $moreparams     Array to provide more information
2355
	 *  @return     int         				0 if KO, 1 if OK
2356
	 */
2357
	public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
2358
	{
2359
		global $conf,$langs;
2360
2361
		$langs->load("orders");
2362
2363
		if (! dol_strlen($modele)) {
2364
2365
			$modele = 'standard';
2366
2367
			if ($this->modelpdf) {
2368
				$modele = $this->modelpdf;
2369
			} elseif (! empty($conf->global->ADHERENT_ADDON_PDF)) {
2370
				$modele = $conf->global->ADHERENT_ADDON_PDF;
2371
			}
2372
		}
2373
2374
		$modelpath = "core/modules/member/doc/";
2375
2376
		return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2377
	}
2378
2379
2380
	/**
2381
	 *  Initialise an instance with random values.
2382
	 *  Used to build previews or test instances.
2383
	 *	id must be 0 if object instance is a specimen.
2384
	 *
2385
	 *  @return	void
2386
	 */
2387
	public function initAsSpecimen()
2388
	{
2389
		global $user,$langs;
2390
2391
		// Initialise parametres
2392
		$this->id=0;
2393
		$this->specimen=1;
2394
		$this->civility_id = 0;
2395
		$this->lastname = 'DOLIBARR';
2396
		$this->firstname = 'SPECIMEN';
2397
		$this->gender='man';
2398
		$this->login='dolibspec';
2399
		$this->pass='dolibspec';
2400
		$this->societe = 'Societe ABC';
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

2400
		/** @scrutinizer ignore-deprecated */ $this->societe = 'Societe ABC';
Loading history...
2401
		$this->address = '61 jump street';
2402
		$this->zip = '75000';
2403
		$this->town = 'Paris';
2404
		$this->country_id = 1;
2405
		$this->country_code = 'FR';
2406
		$this->country = 'France';
2407
		$this->morphy = 'mor';
2408
		$this->email = '[email protected]';
2409
		$this->skype = 'skypepseudo';
2410
		$this->twitter = 'twitterpseudo';
2411
		$this->facebook = 'facebookpseudo';
2412
		$this->linkedin = 'linkedinpseudo';
2413
		$this->phone        = '0999999999';
2414
		$this->phone_perso  = '0999999998';
2415
		$this->phone_mobile = '0999999997';
2416
		$this->note_private='No comment';
2417
		$this->birth=time();
2418
		$this->photo='';
2419
		$this->public=1;
2420
		$this->statut=0;
2421
2422
		$this->datefin=time();
2423
		$this->datevalid=time();
2424
2425
		$this->typeid=1;				// Id type adherent
2426
		$this->type='Type adherent';	// Libelle type adherent
2427
		$this->need_subscription=0;
2428
2429
		$this->first_subscription_date=time();
2430
		$this->first_subscription_date_start=$this->first_subscription_date;
2431
		$this->first_subscription_date_end=dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
2432
		$this->first_subscription_amount=10;
2433
2434
		$this->last_subscription_date=$this->first_subscription_date;
2435
		$this->last_subscription_date_start=$this->first_subscription_date;
2436
		$this->last_subscription_date_end=dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
2437
		$this->last_subscription_amount=10;
2438
	}
2439
2440
2441
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2442
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2443
	/**
2444
	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
2445
	 *
2446
	 *	@param	array	$info		Info array loaded by _load_ldap_info
2447
	 *	@param	int		$mode		0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
2448
	 *								1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
2449
	 *								2=Return key only (uid=qqq)
2450
	 *	@return	string				DN
2451
	 */
2452
	public function _load_ldap_dn($info, $mode = 0)
2453
	{
2454
        // phpcs:enable
2455
		global $conf;
2456
		$dn='';
2457
		if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS].",".$conf->global->LDAP_MEMBER_DN;
2458
		if ($mode==1) $dn=$conf->global->LDAP_MEMBER_DN;
2459
		if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS];
2460
		return $dn;
2461
	}
2462
2463
2464
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2465
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2466
   /**
2467
	 *	Initialise tableau info (tableau des attributs LDAP)
2468
	 *
2469
	 *	@return		array		Tableau info des attributs
2470
	 */
2471
	public function _load_ldap_info()
2472
	{
2473
        // phpcs:enable
2474
		global $conf,$langs;
2475
2476
		$info=array();
2477
		$keymodified=false;
2478
2479
		// Object classes
2480
		$info["objectclass"]=explode(',', $conf->global->LDAP_MEMBER_OBJECT_CLASS);
2481
2482
		$this->fullname=$this->getFullName($langs);
2483
2484
		// For avoid ldap error when firstname and lastname are empty
2485
		if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->societe)) {
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

2485
		if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == /** @scrutinizer ignore-deprecated */ $this->societe)) {
Loading history...
2486
			$this->fullname = $this->societe;
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

2486
			$this->fullname = /** @scrutinizer ignore-deprecated */ $this->societe;
Loading history...
2487
			$this->lastname = $this->societe;
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

2487
			$this->lastname = /** @scrutinizer ignore-deprecated */ $this->societe;
Loading history...
2488
		}
2489
2490
		// Possible LDAP KEY (constname => varname)
2491
		$ldapkey = array(
2492
			'LDAP_MEMBER_FIELD_FULLNAME'		=> 'fullname',
2493
			'LDAP_MEMBER_FIELD_NAME'			=> 'lastname',
2494
			'LDAP_MEMBER_FIELD_LOGIN'		=> 'login',
2495
			'LDAP_MEMBER_FIELD_LOGIN_SAMBA'	=> 'login',
2496
			'LDAP_MEMBER_FIELD_MAIL'			=> 'email'
2497
		);
2498
2499
		// Member
2500
		foreach ($ldapkey as $constname => $varname)
2501
		{
2502
			if (! empty($this->$varname) && ! empty($conf->global->$constname))
2503
			{
2504
				$info[$conf->global->$constname] = $this->$varname;
2505
2506
				// Check if it is the LDAP key and if its value has been changed
2507
				if (! empty($conf->global->LDAP_KEY_MEMBERS) && $conf->global->LDAP_KEY_MEMBERS == $conf->global->$constname)
2508
				{
2509
					if (! empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) $keymodified=true; // For check if LDAP key has been modified
2510
				}
2511
			}
2512
		}
2513
		if ($this->firstname && ! empty($conf->global->LDAP_MEMBER_FIELD_FIRSTNAME))			$info[$conf->global->LDAP_MEMBER_FIELD_FIRSTNAME] = $this->firstname;
2514
		if ($this->poste && ! empty($conf->global->LDAP_MEMBER_FIELD_TITLE))					$info[$conf->global->LDAP_MEMBER_FIELD_TITLE] = $this->poste;
2515
		if ($this->societe && ! empty($conf->global->LDAP_MEMBER_FIELD_COMPANY))				$info[$conf->global->LDAP_MEMBER_FIELD_COMPANY] = $this->societe;
1 ignored issue
show
Deprecated Code introduced by
The property Adherent::$societe has been deprecated. ( Ignorable by Annotation )

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

2515
		if ($this->societe && ! empty($conf->global->LDAP_MEMBER_FIELD_COMPANY))				$info[$conf->global->LDAP_MEMBER_FIELD_COMPANY] = /** @scrutinizer ignore-deprecated */ $this->societe;
Loading history...
2516
		if ($this->address && ! empty($conf->global->LDAP_MEMBER_FIELD_ADDRESS))				$info[$conf->global->LDAP_MEMBER_FIELD_ADDRESS] = $this->address;
2517
		if ($this->zip && ! empty($conf->global->LDAP_MEMBER_FIELD_ZIP))						$info[$conf->global->LDAP_MEMBER_FIELD_ZIP] = $this->zip;
2518
		if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN))						$info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town;
2519
		if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY))			$info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code;
2520
		if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE))					$info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype;
2521
		if ($this->twitter && ! empty($conf->global->LDAP_MEMBER_FIELD_TWITTER))				$info[$conf->global->LDAP_MEMBER_FIELD_TWITTER] = $this->twitter;
2522
		if ($this->facebook && ! empty($conf->global->LDAP_MEMBER_FIELD_FACEBOOK))			$info[$conf->global->LDAP_MEMBER_FIELD_FACEBOOK] = $this->facebook;
2523
		if ($this->linkedin && ! empty($conf->global->LDAP_MEMBER_FIELD_LINKEDIN))			$info[$conf->global->LDAP_MEMBER_FIELD_LINKEDIN] = $this->linkedin;
2524
        if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE))					$info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone;
2525
		if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO))		$info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso;
2526
		if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE))			$info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile;
2527
		if ($this->fax && ! empty($conf->global->LDAP_MEMBER_FIELD_FAX))						$info[$conf->global->LDAP_MEMBER_FIELD_FAX] = $this->fax;
2528
		if ($this->note_private && ! empty($conf->global->LDAP_MEMBER_FIELD_DESCRIPTION))		$info[$conf->global->LDAP_MEMBER_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note_private, 2);
2529
		if ($this->note_public && ! empty($conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC))		$info[$conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC] = dol_string_nohtmltag($this->note_public, 2);
2530
		if ($this->birth && ! empty($conf->global->LDAP_MEMBER_FIELD_BIRTHDATE))				$info[$conf->global->LDAP_MEMBER_FIELD_BIRTHDATE] = dol_print_date($this->birth, 'dayhourldap');
2531
		if (isset($this->statut) && ! empty($conf->global->LDAP_FIELD_MEMBER_STATUS))			$info[$conf->global->LDAP_FIELD_MEMBER_STATUS] = $this->statut;
2532
		if ($this->datefin && ! empty($conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION))	$info[$conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION] = dol_print_date($this->datefin, 'dayhourldap');
2533
2534
		// When password is modified
2535
		if (! empty($this->pass))
2536
		{
2537
			if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD))				$info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass;	// this->pass = mot de passe non crypte
2538
			if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED))		$info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // Create OpenLDAP MD5 password (TODO add type of encryption)
2539
		}
2540
		// Set LDAP password if possible
2541
		elseif ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2542
		{
2543
			if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
2544
			{
2545
				// Just for the default MD5 !
2546
				if (empty($conf->global->MAIN_SECURITY_HASH_ALGO))
2547
				{
2548
					if ($this->pass_indatabase_crypted && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED))	{
2549
						// Create OpenLDAP MD5 password from Dolibarr MD5 password
2550
						// Note: This suppose that "pass_indatabase_crypted" is a md5 (guaranted by the previous test if "(empty($conf->global->MAIN_SECURITY_HASH_ALGO))"
2551
						$info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = '{md5}'.base64_encode(hex2bin($this->pass_indatabase_crypted));
2552
					}
2553
				}
2554
			}
2555
			// Use $this->pass_indatabase value if exists
2556
			elseif (! empty($this->pass_indatabase))
2557
			{
2558
				if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD))				$info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass_indatabase;	// $this->pass_indatabase = mot de passe non crypte
2559
				if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED))		$info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase, 4); // md5 for OpenLdap TODO add type of encryption
2560
			}
2561
		}
2562
2563
		// Subscriptions
2564
		if ($this->first_subscription_date && ! empty($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE))     $info[$conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE]  = dol_print_date($this->first_subscription_date, 'dayhourldap');
2565
		if (isset($this->first_subscription_amount) && ! empty($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT)) $info[$conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT] = $this->first_subscription_amount;
2566
		if ($this->last_subscription_date && ! empty($conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE))       $info[$conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE]   = dol_print_date($this->last_subscription_date, 'dayhourldap');
2567
		if (isset($this->last_subscription_amount) && ! empty($conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT))   $info[$conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT] = $this->last_subscription_amount;
2568
2569
		return $info;
2570
	}
2571
2572
2573
	/**
2574
	 *      Load type info information in the member object
2575
	 *
2576
	 *      @param  int		$id       Id of member to load
2577
	 *      @return	void
2578
	 */
2579
	public function info($id)
2580
	{
2581
		$sql = 'SELECT a.rowid, a.datec as datec,';
2582
		$sql.= ' a.datevalid as datev,';
2583
		$sql.= ' a.tms as datem,';
2584
		$sql.= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2585
		$sql.= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
2586
		$sql.= ' WHERE a.rowid = '.$id;
2587
2588
		dol_syslog(get_class($this)."::info", LOG_DEBUG);
2589
		$result=$this->db->query($sql);
2590
		if ($result)
2591
		{
2592
			if ($this->db->num_rows($result))
2593
			{
2594
				$obj = $this->db->fetch_object($result);
2595
				$this->id = $obj->rowid;
2596
				if ($obj->fk_user_author)
2597
				{
2598
					$cuser = new User($this->db);
2599
					$cuser->fetch($obj->fk_user_author);
2600
					$this->user_creation   = $cuser;
2601
				}
2602
2603
				if ($obj->fk_user_valid)
2604
				{
2605
					$vuser = new User($this->db);
2606
					$vuser->fetch($obj->fk_user_valid);
2607
					$this->user_validation = $vuser;
2608
				}
2609
2610
				if ($obj->fk_user_mod)
2611
				{
2612
					$muser = new User($this->db);
2613
					$muser->fetch($obj->fk_user_mod);
2614
					$this->user_modification = $muser;
2615
				}
2616
2617
				$this->date_creation     = $this->db->jdate($obj->datec);
2618
				$this->date_validation   = $this->db->jdate($obj->datev);
2619
				$this->date_modification = $this->db->jdate($obj->datem);
2620
			}
2621
2622
			$this->db->free($result);
2623
		}
2624
		else
2625
		{
2626
			dol_print_error($this->db);
2627
		}
2628
	}
2629
2630
	/**
2631
	 *  Return number of mass Emailing received by this member with its email
2632
	 *
2633
	 *  @return       int     Number of EMailings
2634
	 */
2635
	public function getNbOfEMailings()
2636
	{
2637
		$sql = "SELECT count(mc.email) as nb";
2638
		$sql.= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
2639
		$sql.= " WHERE mc.email = '".$this->db->escape($this->email)."'";
2640
		$sql.= " AND mc.statut NOT IN (-1,0)";      // -1 erreur, 0 non envoye, 1 envoye avec succes
2641
2642
		$resql=$this->db->query($sql);
2643
		if ($resql)
2644
		{
2645
			$obj = $this->db->fetch_object($resql);
2646
			$nb=$obj->nb;
2647
2648
			$this->db->free($resql);
2649
			return $nb;
2650
		}
2651
		else
2652
		{
2653
			$this->error=$this->db->error();
2654
			return -1;
2655
		}
2656
	}
2657
2658
	/**
2659
	 * Sets object to supplied categories.
2660
	 *
2661
	 * Deletes object from existing categories not supplied.
2662
	 * Adds it to non existing supplied categories.
2663
	 * Existing categories are left untouch.
2664
	 *
2665
	 * @param int[]|int $categories Category or categories IDs
2666
     * @return void
2667
	 */
2668
	public function setCategories($categories)
2669
	{
2670
		// Handle single category
2671
		if (!is_array($categories)) {
2672
			$categories = array($categories);
2673
		}
2674
2675
		// Get current categories
2676
		require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
2677
		$c = new Categorie($this->db);
2678
		$existing = $c->containing($this->id, Categorie::TYPE_MEMBER, 'id');
2679
2680
		// Diff
2681
		if (is_array($existing)) {
0 ignored issues
show
introduced by
The condition is_array($existing) is always false.
Loading history...
2682
			$to_del = array_diff($existing, $categories);
2683
			$to_add = array_diff($categories, $existing);
2684
		} else {
2685
			$to_del = array(); // Nothing to delete
2686
			$to_add = $categories;
2687
		}
2688
2689
		// Process
2690
		foreach ($to_del as $del) {
2691
			if ($c->fetch($del) > 0) {
2692
				$c->del_type($this, 'member');
2693
			}
2694
		}
2695
		foreach ($to_add as $add) {
2696
			if ($c->fetch($add) > 0) {
2697
				$c->add_type($this, 'member');
2698
			}
2699
		}
2700
2701
		return;
2702
	}
2703
2704
	/**
2705
	 * Function used to replace a thirdparty id with another one.
2706
	 *
2707
	 * @param DoliDB 	$db 			Database handler
2708
	 * @param int 		$origin_id 		Old thirdparty id
2709
	 * @param int 		$dest_id 		New thirdparty id
2710
	 * @return bool
2711
	 */
2712
	public static function replaceThirdparty($db, $origin_id, $dest_id)
2713
	{
2714
		$tables = array(
2715
			'adherent'
2716
		);
2717
2718
		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
2719
	}
2720
2721
	/**
2722
	 * Return if a member is late (subscription late) or not
2723
	 *
2724
	 * @return boolean     True if late, False if not late
2725
	 */
2726
	public function hasDelay()
2727
	{
2728
		global $conf;
2729
2730
		//Only valid members
2731
		if ($this->statut <= 0) return false;
2732
		if (! $this->datefin) return false;
2733
2734
		$now = dol_now();
2735
2736
		return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
2737
	}
2738
2739
2740
2741
	/**
2742
	 * Send reminders by emails before subscription end
2743
	 * CAN BE A CRON TASK
2744
	 *
2745
	 * @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'
2746
	 * @return	int									0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
2747
	 */
2748
	public function sendReminderForExpiredSubscription($daysbeforeendlist = '10')
2749
	{
2750
		global $conf, $langs, $mysoc, $user;
2751
2752
		$error = 0;
2753
		$this->output = '';
2754
		$this->error='';
2755
2756
		$blockingerrormsg = '';
2757
2758
		if (empty($conf->adherent->enabled))	// Should not happen. If module disabled, cron job should not be visible.
2759
		{
2760
			$langs->load("agenda");
2761
			$this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
2762
			return 0;
2763
		}
2764
		if (empty($conf->global->MEMBER_REMINDER_EMAIL))
2765
		{
2766
			$langs->load("agenda");
2767
			$this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
2768
			return 0;
2769
		}
2770
2771
		$now = dol_now();
2772
		$nbok = 0;
2773
		$nbko = 0;
2774
2775
		$arraydaysbeforeend=explode(';', $daysbeforeendlist);
2776
		foreach($arraydaysbeforeend as $daysbeforeend)			// Loop on each delay
2777
		{
2778
			dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
2779
2780
			if (! is_numeric($daysbeforeend))
2781
			{
2782
				$blockingerrormsg="Value for delta is not a positive or negative numeric";
2783
				$nbko++;
2784
				break;
2785
			}
2786
2787
			$tmp=dol_getdate($now);
2788
			$datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year']), $daysbeforeend, 'd');
2789
2790
			$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
2791
			$sql.= " WHERE datefin = '".$this->db->idate($datetosearchfor)."'";
2792
2793
			$resql = $this->db->query($sql);
2794
			if ($resql)
2795
			{
2796
				$num_rows = $this->db->num_rows($resql);
2797
2798
				include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2799
				$adherent = new Adherent($this->db);
2800
				$formmail = new FormMail($this->db);
2801
2802
				$i=0;
2803
				while ($i < $num_rows)
2804
				{
2805
					$obj = $this->db->fetch_object($resql);
2806
2807
					$adherent->fetch($obj->rowid, '', '', '', true, true);
2808
2809
					if (empty($adherent->email))
2810
					{
2811
						$nbko++;
2812
					}
2813
					else
2814
					{
2815
						$adherent->fetch_thirdparty();
2816
2817
						// 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.
2818
						$languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : $adherent->thirdparty->country_code);
2819
						$languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
2820
2821
						// Send reminder email
2822
						$outputlangs = new Translate('', $conf);
2823
						$outputlangs->setDefaultLang($languagecodeformember);
2824
						$outputlangs->loadLangs(array("main", "members"));
2825
						dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
2826
2827
						$arraydefaultmessage=null;
2828
						$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION;
2829
2830
						if (! empty($labeltouse)) $arraydefaultmessage=$formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
2831
2832
						if (! empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0)
2833
						{
2834
							$substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
2835
							//if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
2836
							complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
2837
2838
							$subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
2839
							$msg     = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
2840
							$from = $conf->global->ADHERENT_MAIL_FROM;
2841
							$to = $adherent->email;
2842
2843
							$trackid = 'mem'.$adherent->id;
2844
							$moreinheader='X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
2845
2846
							include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
2847
							$cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), '', '', 0, 1, '', '', $trackid, $moreinheader);
2848
							$result = $cmail->sendfile();
2849
							if (! $result)
2850
							{
2851
								$error++;
2852
								$this->error = $cmail->error;
2853
								$this->errors += $cmail->errors;
2854
								$nbko++;
2855
							}
2856
							else
2857
							{
2858
								$nbok++;
2859
2860
								$message = $msg;
2861
								$sendto = $to;
2862
								$sendtocc = '';
2863
								$sendtobcc = '';
2864
								$actioncode='EMAIL';
2865
								$extraparams='';
2866
2867
								$actionmsg='';
2868
								$actionmsg2=$langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from, 4, 0, 1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($sendto, 4, 0, 1);
2869
								if ($message)
2870
								{
2871
									$actionmsg=$langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
2872
									$actionmsg=dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
2873
									if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . dol_escape_htmltag($sendtocc));
2874
									$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
2875
									$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
2876
									$actionmsg = dol_concatdesc($actionmsg, $message);
2877
								}
2878
2879
								require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
2880
2881
	    						// Insert record of emails sent
2882
	    						$actioncomm = new ActionComm($this->db);
2883
2884
	    						$actioncomm->type_code   = 'AC_OTH_AUTO';		// Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
2885
	    						$actioncomm->code        = 'AC_'.$actioncode;
2886
	    						$actioncomm->label       = $actionmsg2;
2887
	    						$actioncomm->note        = $actionmsg;
1 ignored issue
show
Deprecated Code introduced by
The property CommonObject::$note has been deprecated. ( Ignorable by Annotation )

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

2887
	    						/** @scrutinizer ignore-deprecated */ $actioncomm->note        = $actionmsg;
Loading history...
2888
	    						$actioncomm->fk_project  = 0;
2889
	    						$actioncomm->datep       = $now;
2890
	    						$actioncomm->datef       = $now;
2891
	    						$actioncomm->percentage  = -1;   // Not applicable
2892
	    						$actioncomm->socid       = $adherent->thirdparty->id;
2893
	    						$actioncomm->contactid   = 0;
2894
	    						$actioncomm->authorid    = $user->id;   // User saving action
2895
	    						$actioncomm->userownerid = $user->id;	// Owner of action
2896
	    						// Fields when action is en email (content should be added into note)
2897
	    						$actioncomm->email_msgid = $cmail->msgid;
0 ignored issues
show
Bug introduced by
The property msgid does not seem to exist on CMailFile.
Loading history...
2898
	    						$actioncomm->email_from  = $from;
2899
	    						$actioncomm->email_sender= '';
2900
	    						$actioncomm->email_to    = $to;
2901
	    						$actioncomm->email_tocc  = $sendtocc;
2902
	    						$actioncomm->email_tobcc = $sendtobcc;
2903
	    						$actioncomm->email_subject = $subject;
2904
	    						$actioncomm->errors_to   = '';
2905
2906
	    						$actioncomm->fk_element  = $adherent->id;
2907
	    						$actioncomm->elementtype = $adherent->element;
2908
2909
	    						$actioncomm->extraparams = $extraparams;
0 ignored issues
show
Bug introduced by
The property extraparams does not seem to exist on ActionComm.
Loading history...
2910
2911
	    						$actioncomm->create($user);
2912
							}
2913
						}
2914
						else
2915
						{
2916
							$blockingerrormsg="Can't find email template, defined into member module setup, to use for reminding";
2917
							$nbko++;
2918
							break;
2919
						}
2920
					}
2921
2922
					$i++;
2923
				}
2924
			}
2925
			else
2926
			{
2927
				$this->error = $this->db->lasterror();
2928
				return 1;
2929
			}
2930
		}
2931
2932
		if ($blockingerrormsg)
2933
		{
2934
			$this->error = $blockingerrormsg;
2935
			return 1;
2936
		}
2937
		else
2938
		{
2939
			$this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
2940
			$this->output.= ' Send email successfuly to '.$nbok.' members';
2941
			if ($nbko) $this->output.= ' - Canceled for '.$nbko.' member (no email or email sending error)';
2942
		}
2943
2944
		return 0;
2945
	}
2946
}
2947