Completed
Branch develop (517301)
by
unknown
36:51
created

Adherent::LibStatut()   F

Complexity

Conditions 43
Paths 763

Size

Total Lines 82
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 43
eloc 52
nc 763
nop 4
dl 0
loc 82
rs 2.439
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* 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-2016	Alexandre Spangaro		<[email protected]>
9
 * Copyright (C) 2015		Marcos García			<[email protected]>
10
 * Copyright (C) 2015		Frederic France			<[email protected]>
11
 * Copyright (C) 2015		Raphaël Doursenaud		<[email protected]>
12
 * Copyright (C) 2016		Juanjo Menent			<[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26
 */
27
28
/**
29
 *	\file       htdocs/adherents/class/adherent.class.php
30
 *	\ingroup    member
31
 *	\brief      File of class to manage members of a foundation
32
 */
33
34
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
35
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
36
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
37
38
39
/**
40
 *		Class to manage members of a foundation
41
 */
42
class Adherent extends CommonObject
43
{
44
	public $element='member';
45
	public $table_element='adherent';
46
	public $ismultientitymanaged = 1;  // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
47
48
	var $mesgs;
49
50
	var $login;
51
52
	//! Clear password in memory
53
	var $pass;
54
	//! Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
55
	var $pass_indatabase;
56
	//! Encrypted password in database (always defined)
57
	var $pass_indatabase_crypted;
58
59
	var $societe;
60
	var $company;
61
	var $address;
62
	var $zip;
63
	var $town;
64
65
	var $state_id;              // Id of department
66
	var $state_code;            // Code of department
67
	var $state;                 // Label of department
68
69
	var $email;
70
	var $skype;
71
	var $phone;
72
	var $phone_perso;
73
	var $phone_mobile;
74
75
	var $morphy;
76
	var $public;
77
	var $statut;			// -1:brouillon, 0:resilie, >=1:valide,paye
78
	var $photo;
79
80
	var $datec;
81
	var $datem;
82
	var $datefin;
83
	var $datevalid;
84
	var $birth;
85
86
	var $note_public;
87
	var $note_private;
88
89
	var $typeid;			// Id type adherent
90
	var $type;				// Libelle type adherent
91
	var $need_subscription;
92
93
	var $user_id;
94
	var $user_login;
95
96
	var $fk_soc;
97
98
	// Fields loaded by fetch_subscriptions()
99
	var $first_subscription_date;
100
	var $first_subscription_amount;
101
	var $last_subscription_date;
102
	var $last_subscription_date_start;
103
	var $last_subscription_date_end;
104
	var $last_subscription_amount;
105
	var $subscriptions=array();
106
107
	var $oldcopy;		// To contains a clone of this when we need to save old properties of object
108
109
	public $entity;
110
111
	/**
112
	 *	Constructor
113
	 *
114
	 *	@param 		DoliDB		$db		Database handler
115
	 */
116
	function __construct($db)
117
	{
118
		$this->db = $db;
119
		$this->statut = -1;
120
		// l'adherent n'est pas public par defaut
121
		$this->public = 0;
122
		// les champs optionnels sont vides
123
		$this->array_options=array();
124
	}
125
126
127
	/**
128
	 *  Function sending an email has the adherent with the text supplied in parameter.
129
	 *
130
	 *  @param	string	$text				Content of message (not html entities encoded)
131
	 *  @param	string	$subject			Subject of message
132
	 *  @param 	array	$filename_list      Array of attached files
133
	 *  @param 	array	$mimetype_list      Array of mime types of attached files
134
	 *  @param 	array	$mimefilename_list  Array of public names of attached files
135
	 *  @param 	string	$addr_cc            Email cc
136
	 *  @param 	string	$addr_bcc           Email bcc
137
	 *  @param 	int		$deliveryreceipt	Ask a delivery receipt
138
	 *  @param	int		$msgishtml			1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
139
	 *  @param	string	$errors_to			erros to
140
	 *  @return	int							<0 if KO, >0 if OK
141
	 */
142
	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='')
143
	{
144
		global $conf,$langs;
145
146
		// Detect if message is HTML
147
		if ($msgishtml == -1)
148
		{
149
			$msgishtml = 0;
150
			if (dol_textishtml($text,1)) $msgishtml = 1;
151
		}
152
153
		$texttosend=$this->makeSubstitution($text);
154
		$subjecttosend=$this->makeSubstitution($subject);
155
		if ($msgishtml) $texttosend=dol_htmlentitiesbr($texttosend);
156
157
		// Envoi mail confirmation
158
		$from=$conf->email_from;
159
		if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM;
160
161
		// Send email (substitutionarray must be done just before this)
162
		include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
163
		$mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml);
164
		if ($mailfile->sendfile())
165
		{
166
			return 1;
167
		}
168
		else
169
		{
170
			$this->error=$langs->trans("ErrorFailedToSendMail",$from,$this->email).'. '.$mailfile->error;
171
			return -1;
172
		}
173
	}
174
175
176
	/**
177
	 * Make substitution of tags into text with value of current object.
178
	 *
179
	 * @param	string	$text       Text to make substitution to
180
	 * @return  string      		Value of input text string with substitutions done
181
	 */
182
	function makeSubstitution($text)
183
	{
184
		global $conf,$langs;
185
186
		$birthday = dol_print_date($this->birth,'day');
187
188
		$msgishtml = 0;
189
		if (dol_textishtml($text,1)) $msgishtml = 1;
190
191
		$infos='';
192
		if ($this->civility_id) $infos.= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
193
		$infos.= $langs->transnoentities("id").": ".$this->id."\n";
194
		$infos.= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
195
		$infos.= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
196
		$infos.= $langs->transnoentities("Company").": ".$this->societe."\n";
197
		$infos.= $langs->transnoentities("Address").": ".$this->address."\n";
198
		$infos.= $langs->transnoentities("Zip").": ".$this->zip."\n";
199
		$infos.= $langs->transnoentities("Town").": ".$this->town."\n";
200
		$infos.= $langs->transnoentities("Country").": ".$this->country."\n";
201
		$infos.= $langs->transnoentities("EMail").": ".$this->email."\n";
202
		$infos.= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
203
		$infos.= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
204
		$infos.= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
205
		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
206
		{
207
			$infos.= $langs->transnoentities("Login").": ".$this->login."\n";
208
			$infos.= $langs->transnoentities("Password").": ".$this->pass."\n";
209
		}
210
		$infos.= $langs->transnoentities("Birthday").": ".$birthday."\n";
211
		$infos.= $langs->transnoentities("Photo").": ".$this->photo."\n";
212
		$infos.= $langs->transnoentities("Public").": ".yn($this->public);
213
214
		// Substitutions
215
		$substitutionarray=array(
216
			'__CIVILITY__'=>$this->getCivilityLabel(),
217
			'__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname,
218
			'__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname,
219
			'__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs),
220
			'__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe,
221
			'__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address,
222
			'__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip,
223
			'__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town,
224
			'__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country,
225
			'__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email,
226
			'__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday,
227
			'__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo,
228
			'__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login,
229
			'__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass,
230
			'__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):$this->phone,
231
			'__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):$this->phone_perso,
232
			'__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):$this->phone_mobile,
233
		);
234
235
		complete_substitutions_array($substitutionarray, $langs, $this);
236
237
		return make_substitutions($text, $substitutionarray, $langs);
238
	}
239
240
241
	/**
242
	 *	Return translated label by the nature of a adherent (physical or moral)
243
	 *
244
	 *	@param	string		$morphy		Nature of the adherent (physical or moral)
245
	 *	@return	string					Label
246
	 */
247
	function getmorphylib($morphy='')
248
	{
249
		global $langs;
250
		if (! $morphy) { $morphy=$this->morphy; }
251
		if ($morphy == 'phy') { return $langs->trans("Physical"); }
252
		if ($morphy == 'mor') { return $langs->trans("Moral"); }
253
		return $morphy;
254
	}
255
256
	/**
257
	 *	Create a member into database
258
	 *
259
	 *	@param	User	$user        	Objet user qui demande la creation
260
	 *	@param  int		$notrigger		1 ne declenche pas les triggers, 0 sinon
261
	 *	@return	int						<0 if KO, >0 if OK
262
	 */
263
	function create($user,$notrigger=0)
264
	{
265
		global $conf,$langs;
266
267
		$error=0;
268
269
		$now=dol_now();
270
271
		// Clean parameters
272
		$this->import_key = trim($this->import_key);
273
274
		// Check parameters
275
		if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
276
		{
277
			$langs->load("errors");
278
			$this->error = $langs->trans("ErrorBadEMail",$this->email);
279
			return -1;
280
		}
281
		if (! $this->datec) $this->datec=$now;
282
		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
283
		{
284
			if (empty($this->login))
285
			{
286
				$this->error = $langs->trans("ErrorWrongValueForParameterX","Login");
287
				return -1;
288
			}
289
		}
290
291
		$this->db->begin();
292
293
		// Insert member
294
		$sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
295
		$sql.= " (datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key)";
296
		$sql.= " VALUES (";
297
		$sql.= " '".$this->db->idate($this->datec)."'";
298
		$sql.= ", ".($this->login?"'".$this->db->escape($this->login)."'":"null");
299
		$sql.= ", ".($user->id>0?$user->id:"null");	// Can be null because member can be created by a guest or a script
300
		$sql.= ", null, null, '".$this->db->escape($this->morphy)."'";
301
		$sql.= ", ".$this->typeid;
302
		$sql.= ", ".$conf->entity;
303
		$sql.= ", ".(! empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'":"null");
304
		$sql.= ")";
305
306
		dol_syslog(get_class($this)."::create", LOG_DEBUG);
307
		$result = $this->db->query($sql);
308
		if ($result)
309
		{
310
			$id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
311
			if ($id > 0)
312
			{
313
				$this->id=$id;
314
				$this->ref=(string) $id;
315
316
				// Update minor fields
317
				$result=$this->update($user,1,1,0,0,'add'); // nosync is 1 to avoid update data of user
318
				if ($result < 0)
319
				{
320
					$this->db->rollback();
321
					return -1;
322
				}
323
324
				// Add link to user
325
				if ($this->user_id)
326
				{
327
					// Add link to user
328
					$sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
329
					$sql.= " fk_member = ".$this->id;
330
					$sql.= " WHERE rowid = ".$this->user_id;
331
					dol_syslog(get_class($this)."::create", LOG_DEBUG);
332
					$resql = $this->db->query($sql);
333
					if (! $resql)
334
					{
335
						$this->error='Failed to update user to make link with member';
336
						$this->db->rollback();
337
						return -4;
338
					}
339
				}
340
341
				if (! $notrigger)
342
				{
343
					// Call trigger
344
					$result=$this->call_trigger('MEMBER_CREATE',$user);
345
					if ($result < 0) { $error++; }
346
					// End call triggers
347
				}
348
349
				if (count($this->errors))
350
				{
351
					dol_syslog(get_class($this)."::create ".implode(',',$this->errors), LOG_ERR);
352
					$this->db->rollback();
353
					return -3;
354
				}
355
				else
356
				{
357
					$this->db->commit();
358
					return $this->id;
359
				}
360
			}
361
			else
362
			{
363
				$this->error='Failed to get last insert id';
364
				dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
365
				$this->db->rollback();
366
				return -2;
367
			}
368
		}
369
		else
370
		{
371
			$this->error=$this->db->error();
372
			$this->db->rollback();
373
			return -1;
374
		}
375
	}
376
377
378
	/**
379
	 *	Update a member in database (standard information and password)
380
	 *
381
	 *	@param	User	$user				User making update
382
	 *	@param	int		$notrigger			1=disable trigger UPDATE (when called by create)
383
	 *	@param	int		$nosyncuser			0=Synchronize linked user (standard info), 1=Do not synchronize linked user
384
	 *	@param	int		$nosyncuserpass		0=Synchronize linked user (password), 1=Do not synchronize linked user
385
	 *	@param	int		$nosyncthirdparty	0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty
386
	 * 	@param	string	$action				Current action for hookmanager
387
	 * 	@return	int							<0 if KO, >0 if OK
388
	 */
389
	function update($user,$notrigger=0,$nosyncuser=0,$nosyncuserpass=0,$nosyncthirdparty=0,$action='update')
390
	{
391
		global $conf, $langs, $hookmanager;
392
393
		$nbrowsaffected=0;
394
		$error=0;
395
396
		dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
397
398
		// Clean parameters
399
		$this->lastname=trim($this->lastname)?trim($this->lastname):trim($this->lastname);
400
		$this->firstname=trim($this->firstname)?trim($this->firstname):trim($this->firstname);
401
		$this->address=($this->address?$this->address:$this->address);
402
		$this->zip=($this->zip?$this->zip:$this->zip);
403
		$this->town=($this->town?$this->town:$this->town);
404
		$this->country_id=($this->country_id > 0?$this->country_id:$this->country_id);
405
		$this->state_id=($this->state_id > 0?$this->state_id:$this->state_id);
406
		if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname=ucwords(trim($this->lastname));
407
		if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname));
408
		$this->note_public=($this->note_public?$this->note_public:$this->note_public);
409
		$this->note_private=($this->note_private?$this->note_private:$this->note_private);
410
411
		// Check parameters
412
		if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
413
		{
414
			$langs->load("errors");
415
			$this->error = $langs->trans("ErrorBadEMail",$this->email);
416
			return -1;
417
		}
418
419
		$this->db->begin();
420
421
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
422
		$sql.= " civility = ".($this->civility_id?"'".$this->db->escape($this->civility_id)."'":"null");
423
		$sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null");
424
		$sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null");
425
		$sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null");
426
		$sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null");
427
		$sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null");
428
		$sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null");
429
		$sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null");
430
		$sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null");
431
		$sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null");
432
		$sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null");
433
		$sql.= ", email = '".$this->db->escape($this->email)."'";
434
		$sql.= ", skype = '".$this->db->escape($this->skype)."'";
435
		$sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null");
436
		$sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null");
437
		$sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null");
438
		$sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
439
		$sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
440
		$sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null");
441
		$sql.= ", public = '".$this->db->escape($this->public)."'";
442
		$sql.= ", statut = ".$this->db->escape($this->statut);
443
		$sql.= ", fk_adherent_type = ".$this->db->escape($this->typeid);
444
		$sql.= ", morphy = '".$this->db->escape($this->morphy)."'";
445
		$sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null");
446
		if ($this->datefin)   $sql.= ", datefin = '".$this->db->idate($this->datefin)."'";		// Must be modified only when deleting a subscription
447
		if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'";	// Must be modified only when validating a member
448
		$sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null');	// Can be null because member can be create by a guest
449
		$sql.= " WHERE rowid = ".$this->id;
450
451
		dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
452
		$resql = $this->db->query($sql);
453
		if ($resql)
454
		{
455
			unset($this->country_code);
456
			unset($this->country);
457
			unset($this->state_code);
458
			unset($this->state);
459
460
			$nbrowsaffected+=$this->db->affected_rows($resql);
461
462
			$action='update';
463
464
			// Actions on extra fields (by external module)
465
			// TODO le hook fait double emploi avec le trigger !!
466
			$hookmanager->initHooks(array('memberdao'));
467
			$parameters=array('id'=>$this->id);
468
			$action='';
469
			$reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
470
			if (empty($reshook))
471
			{
472
				if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
473
				{
474
					$result=$this->insertExtraFields();
475
					if ($result < 0)
476
					{
477
						$error++;
478
					}
479
				}
480
			}
481
			else if ($reshook < 0) $error++;
482
483
			// Update password
484
			if (! $error && $this->pass)
485
			{
486
				dol_syslog(get_class($this)."::update update password");
487
				if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted)
488
				{
489
					$isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1;
490
491
					// If password to set differs from the one found into database
492
					$result=$this->setPassword($user,$this->pass,$isencrypted,$notrigger,$nosyncuserpass);
493
					if (! $nbrowsaffected) $nbrowsaffected++;
494
				}
495
			}
496
497
			// Remove links to user and replace with new one
498
			if (! $error)
499
			{
500
				dol_syslog(get_class($this)."::update update link to user");
501
				$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
502
				dol_syslog(get_class($this)."::update", LOG_DEBUG);
503
				$resql = $this->db->query($sql);
504
				if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
505
				// If there is a user linked to this member
506
				if ($this->user_id > 0)
507
				{
508
					$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id." WHERE rowid = ".$this->user_id;
509
					dol_syslog(get_class($this)."::update", LOG_DEBUG);
510
					$resql = $this->db->query($sql);
511
					if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
512
				}
513
			}
514
515
			if (! $error && $nbrowsaffected)	// If something has change in main data
516
			{
517
				// Update information on linked user if it is an update
518
				if (! $error && $this->user_id > 0 && ! $nosyncuser)
519
				{
520
					require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
521
522
					dol_syslog(get_class($this)."::update update linked user");
523
524
					$luser=new User($this->db);
525
					$result=$luser->fetch($this->user_id);
526
527
					if ($result >= 0)
528
					{
529
						//var_dump($this->user_login);exit;
530
						//var_dump($this->login);exit;
531
532
						// 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.
533
						if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) $luser->login=$this->login;
534
535
						$luser->civility_id=$this->civility_id;
536
						$luser->firstname=$this->firstname;
537
						$luser->lastname=$this->lastname;
538
						$luser->pass=$this->pass;
539
						$luser->societe_id=$this->societe;
540
541
						$luser->email=$this->email;
542
						$luser->skype=$this->skype;
543
						$luser->office_phone=$this->phone;
544
						$luser->user_mobile=$this->phone_mobile;
545
546
						$luser->fk_member=$this->id;
547
548
						$result=$luser->update($user,0,1,1);	// Use nosync to 1 to avoid cyclic updates
549
						if ($result < 0)
550
						{
551
							$this->error=$luser->error;
552
							dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
553
							$error++;
554
						}
555
					}
556
					else
557
					{
558
						$this->error=$luser->error;
559
						$error++;
560
					}
561
				}
562
563
				// Update information on linked thirdparty if it is an update
564
				if (! $error && $this->fk_soc > 0 && ! $nosyncthirdparty)
565
				{
566
					require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
567
568
					dol_syslog(get_class($this)."::update update linked thirdparty");
569
570
					// This member is linked with a thirdparty, so we also update thirdparty informations
571
					// if this is an update.
572
					$lthirdparty=new Societe($this->db);
573
					$result=$lthirdparty->fetch($this->fk_soc);
574
575
					if ($result >= 0)
576
					{
577
						$lthirdparty->address=$this->address;
578
						$lthirdparty->zip=$this->zip;
579
						$lthirdparty->town=$this->town;
580
						$lthirdparty->email=$this->email;
581
						$lthirdparty->skype=$this->skype;
582
						$lthirdparty->phone=$this->phone;
583
						$lthirdparty->state_id=$this->state_id;
584
						$lthirdparty->country_id=$this->country_id;
585
						$lthirdparty->country_id=$this->country_id;
586
						//$lthirdparty->phone_mobile=$this->phone_mobile;
587
588
						$result=$lthirdparty->update($this->fk_soc,$user,0,1,1,'update');	// Use sync to 0 to avoid cyclic updates
589
						if ($result < 0)
590
						{
591
							$this->error=$lthirdparty->error;
592
							dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
593
							$error++;
594
						}
595
					}
596
					else
597
					{
598
						$this->error=$lthirdparty->error;
599
						$error++;
600
					}
601
				}
602
603
				if (! $error && ! $notrigger)
604
				{
605
					// Call trigger
606
					$result=$this->call_trigger('MEMBER_MODIFY',$user);
607
					if ($result < 0) { $error++; }
608
					// End call triggers
609
				}
610
			}
611
612
			if (! $error)
613
			{
614
				$this->db->commit();
615
				return $nbrowsaffected;
616
			}
617
			else
618
			{
619
				$this->db->rollback();
620
				return -1;
621
			}
622
		}
623
		else
624
		{
625
			$this->db->rollback();
626
			$this->error=$this->db->lasterror();
627
			return -2;
628
		}
629
	}
630
631
632
	/**
633
	 *	Update denormalized last subscription date.
634
	 * 	This function is called when we delete a subscription for example.
635
	 *
636
	 *	@param	User	$user			User making change
637
	 *	@return	int						<0 if KO, >0 if OK
638
	 */
639
	function update_end_date($user)
640
	{
641
		$this->db->begin();
642
643
		// Search for last subscription id and end date
644
		$sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
645
		$sql.= " FROM ".MAIN_DB_PREFIX."subscription";
646
		$sql.= " WHERE fk_adherent=".$this->id;
647
		$sql.= " ORDER by dateadh DESC";	// Sort by start subscription date
648
649
		dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
650
		$resql=$this->db->query($sql);
651
		if ($resql)
652
		{
653
			$obj=$this->db->fetch_object($resql);
654
			$dateop=$this->db->jdate($obj->dateop);
655
			$datedeb=$this->db->jdate($obj->datedeb);
656
			$datefin=$this->db->jdate($obj->datefin);
657
658
			$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
659
			$sql.= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
660
			$sql.= " WHERE rowid = ".$this->id;
661
662
			dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
663
			$resql=$this->db->query($sql);
664
			if ($resql)
665
			{
666
				$this->last_subscription_date=$dateop;
667
				$this->last_subscription_date_start=$datedeb;
668
				$this->last_subscription_date_end=$datefin;
669
				$this->datefin=$datefin;
670
				$this->db->commit();
671
				return 1;
672
			}
673
			else
674
			{
675
				$this->db->rollback();
676
				return -1;
677
			}
678
		}
679
		else
680
		{
681
			$this->error=$this->db->lasterror();
682
			$this->db->rollback();
683
			return -1;
684
		}
685
686
	}
687
688
	/**
689
	 *  Fonction qui supprime l'adherent et les donnees associees
690
	 *
691
	 *  @param	int		$rowid		Id of member to delete
692
	 *	@param	User		$user		User object
693
	 *	@param	int		$notrigger	1=Does not execute triggers, 0= execute triggers
694
	 *  @return	int					<0 if KO, 0=nothing to do, >0 if OK
695
	 */
696
	function delete($rowid, $user, $notrigger=0)
697
	{
698
		global $conf, $langs;
699
700
		$result = 0;
701
		$error=0;
702
		$errorflag=0;
703
704
		// Check parameters
705
		if (empty($rowid)) $rowid=$this->id;
706
707
		$this->db->begin();
708
709
		if (! $error && ! $notrigger)
710
		{
711
			// Call trigger
712
			$result=$this->call_trigger('MEMBER_DELETE',$user);
713
			if ($result < 0) $error++;
714
			// End call triggers
715
		}
716
717
		// Remove category
718
		$sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid;
719
		dol_syslog(get_class($this)."::delete", LOG_DEBUG);
720
		$resql=$this->db->query($sql);
721
		if (! $resql)
722
		{
723
			$error++;
724
			$this->error .= $this->db->lasterror();
725
			$errorflag=-1;
726
		}
727
728
		// Remove subscription
729
		if (! $error)
730
		{
731
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid;
732
			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
733
			$resql=$this->db->query($sql);
734
			if (! $resql)
735
			{
736
				$error++;
737
				$this->error .= $this->db->lasterror();
738
				$errorflag=-2;
739
			}
740
		}
741
742
		// Remove linked user
743
		if (! $error)
744
		{
745
			$ret=$this->setUserId(0);
746
			if ($ret < 0)
747
			{
748
				$error++;
749
				$this->error .= $this->db->lasterror();
750
				$errorflag=-3;
751
			}
752
		}
753
754
		// Removed extrafields
755
		if (! $error)
756
		{
757
			if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
758
			{
759
				$result=$this->deleteExtraFields();
760
				if ($result < 0)
761
				{
762
					$error++;
763
					$errorflag=-4;
764
					dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
765
				}
766
			}
767
		}
768
769
		// Remove adherent
770
		if (! $error)
771
		{
772
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid;
773
			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
774
			$resql=$this->db->query($sql);
775
			if (! $resql)
776
			{
777
				$error++;
778
				$this->error .= $this->db->lasterror();
779
				$errorflag=-5;
780
			}
781
		}
782
783
		if (! $error)
784
		{
785
			$this->db->commit();
786
			return 1;
787
		}
788
		else
789
		{
790
			$this->db->rollback();
791
			return $errorflag;
792
		}
793
	}
794
795
796
	/**
797
	 *    Change password of a user
798
	 *
799
	 *    @param	User	$user           Object user de l'utilisateur qui fait la modification
800
	 *    @param 	string	$password       New password (to generate if empty)
801
	 *    @param    int		$isencrypted    0 ou 1 si il faut crypter le mot de passe en base (0 par defaut)
802
	 *	  @param	int		$notrigger		1=Ne declenche pas les triggers
803
	 *    @param	int		$nosyncuser		Do not synchronize linked user
804
	 *    @return   string           		If OK return clear password, 0 if no change, < 0 if error
805
	 */
806
	function setPassword($user, $password='', $isencrypted=0, $notrigger=0, $nosyncuser=0)
807
	{
808
		global $conf, $langs;
809
810
		$error=0;
811
812
		dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." isencrypted=".$isencrypted);
813
814
		// If new password not provided, we generate one
815
		if (! $password)
816
		{
817
			require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
818
			$password=getRandomPassword(false);
819
		}
820
821
		// Crypt password
822
		$password_crypted = dol_hash($password);
823
824
		$password_indatabase = '';
825
		if (! $isencrypted)
826
		{
827
			$password_indatabase = $password;
828
		}
829
830
		$this->db->begin();
831
832
		// Mise a jour
833
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
834
		$sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
835
		//if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
836
		if ($isencrypted)
837
		{
838
			$sql.= ", pass = null";
839
		}
840
		else
841
		{
842
			$sql.= ", pass = '".$this->db->escape($password_indatabase)."'";
843
		}
844
		$sql.= " WHERE rowid = ".$this->id;
845
846
		//dol_syslog("Adherent::Password sql=hidden");
847
		dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
848
		$result = $this->db->query($sql);
849
		if ($result)
850
		{
851
			$nbaffectedrows=$this->db->affected_rows($result);
852
853
			if ($nbaffectedrows)
854
			{
855
				$this->pass=$password;
856
				$this->pass_indatabase=$password_indatabase;
857
				$this->pass_indatabase_crypted=$password_crypted;
858
859
				if ($this->user_id && ! $nosyncuser)
860
				{
861
					require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
862
863
					// This member is linked with a user, so we also update users informations
864
					// if this is an update.
865
					$luser=new User($this->db);
866
					$result=$luser->fetch($this->user_id);
867
868
					if ($result >= 0)
869
					{
870
						$result=$luser->setPassword($user,$this->pass,0,0,1);
871
						if ($result < 0)
872
						{
873
							$this->error=$luser->error;
874
							dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR);
875
							$error++;
876
						}
877
					}
878
					else
879
					{
880
						$this->error=$luser->error;
881
						$error++;
882
					}
883
				}
884
885
				if (! $error && ! $notrigger)
886
				{
887
					// Call trigger
888
					$result=$this->call_trigger('MEMBER_NEW_PASSWORD',$user);
889
					if ($result < 0) { $error++; $this->db->rollback(); return -1; }
890
					// End call triggers
891
				}
892
893
				$this->db->commit();
894
				return $this->pass;
895
			}
896
			else
897
			{
898
				$this->db->rollback();
899
				return 0;
900
			}
901
		}
902
		else
903
		{
904
			$this->db->rollback();
905
			dol_print_error($this->db);
906
			return -1;
907
		}
908
	}
909
910
911
	/**
912
	 *    Set link to a user
913
	 *
914
	 *    @param     int	$userid        	Id of user to link to
915
	 *    @return    int					1=OK, -1=KO
916
	 */
917
	function setUserId($userid)
918
	{
919
		global $conf, $langs;
920
921
		$this->db->begin();
922
923
		// If user is linked to this member, remove old link to this member
924
		$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
925
		dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
926
		$resql = $this->db->query($sql);
927
		if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -1; }
928
929
		// Set link to user
930
		if ($userid > 0)
931
		{
932
			$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id;
933
			$sql.= " WHERE rowid = ".$userid;
934
			dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
935
			$resql = $this->db->query($sql);
936
			if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -2; }
937
		}
938
939
		$this->db->commit();
940
941
		return 1;
942
	}
943
944
945
	/**
946
	 *    Set link to a third party
947
	 *
948
	 *    @param     int	$thirdpartyid		Id of user to link to
949
	 *    @return    int						1=OK, -1=KO
950
	 */
951
	function setThirdPartyId($thirdpartyid)
952
	{
953
		global $conf, $langs;
954
955
		$this->db->begin();
956
957
		// Remove link to third party onto any other members
958
		if ($thirdpartyid > 0)
959
		{
960
			$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
961
			$sql.= " WHERE fk_soc = '".$thirdpartyid."'";
962
			$sql.= " AND entity = ".$conf->entity;
963
			dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
964
			$resql = $this->db->query($sql);
965
		}
966
967
		// Add link to third party for current member
968
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid>0 ? $thirdpartyid : 'null');
969
		$sql.= " WHERE rowid = ".$this->id;
970
971
		dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
972
		$resql = $this->db->query($sql);
973
		if ($resql)
974
		{
975
			$this->db->commit();
976
			return 1;
977
		}
978
		else
979
		{
980
			$this->error=$this->db->error();
981
			$this->db->rollback();
982
			return -1;
983
		}
984
	}
985
986
987
	/**
988
	 *	Method to load member from its login
989
	 *
990
	 *	@param	string	$login		login of member
991
	 *	@return	void
992
	 */
993
	function fetch_login($login)
994
	{
995
		global $conf;
996
997
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
998
		$sql.= " WHERE login='".$this->db->escape($login)."'";
999
		$sql.= " AND entity = ".$conf->entity;
1000
1001
		$resql=$this->db->query($sql);
1002
		if ($resql)
1003
		{
1004
			if ($this->db->num_rows($resql))
1005
			{
1006
				$obj = $this->db->fetch_object($resql);
1007
				$this->fetch($obj->rowid);
1008
			}
1009
		}
1010
		else
1011
		{
1012
			dol_print_error($this->db);
1013
		}
1014
	}
1015
1016
	/**
1017
	 *	Method to load member from its name
1018
	 *
1019
	 *	@param	string	$firstname	Firstname
1020
	 *	@param	string	$lastname	Lastname
1021
	 *	@return	void
1022
	 */
1023
	function fetch_name($firstname,$lastname)
1024
	{
1025
		global $conf;
1026
1027
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
1028
		$sql.= " WHERE firstname='".$this->db->escape($firstname)."'";
1029
		$sql.= " AND lastname='".$this->db->escape($lastname)."'";
1030
		$sql.= " AND entity = ".$conf->entity;
1031
1032
		$resql=$this->db->query($sql);
1033
		if ($resql)
1034
		{
1035
			if ($this->db->num_rows($resql))
1036
			{
1037
				$obj = $this->db->fetch_object($resql);
1038
				$this->fetch($obj->rowid);
1039
			}
1040
		}
1041
		else
1042
		{
1043
			dol_print_error($this->db);
1044
		}
1045
	}
1046
1047
	/**
1048
	 *	Load member from database
1049
	 *
1050
	 *	@param	int		$rowid      Id of object to load
1051
	 * 	@param	string	$ref		To load member from its ref
1052
	 * 	@param	int		$fk_soc		To load member from its link to third party
1053
	 * 	@param	string	$ref_ext	External reference
1054
	 *	@return int         		>0 if OK, 0 if not found, <0 if KO
1055
	 */
1056
	function fetch($rowid,$ref='',$fk_soc='',$ref_ext='')
1057
	{
1058
		global $langs;
1059
1060
		$sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
1061
		$sql.= " d.note_public,";
1062
		$sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
1063
		$sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
1064
		$sql.= " d.datec as datec,";
1065
		$sql.= " d.tms as datem,";
1066
		$sql.= " d.datefin as datefin,";
1067
		$sql.= " d.birth as birthday,";
1068
		$sql.= " d.datevalid as datev,";
1069
		$sql.= " d.country,";
1070
		$sql.= " d.state_id,";
1071
		$sql.= " d.model_pdf,";
1072
		$sql.= " c.rowid as country_id, c.code as country_code, c.label as country,";
1073
		$sql.= " dep.nom as state, dep.code_departement as state_code,";
1074
		$sql.= " t.libelle as type, t.subscription as subscription,";
1075
		$sql.= " u.rowid as user_id, u.login as user_login";
1076
		$sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
1077
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
1078
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
1079
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
1080
		$sql.= " WHERE d.fk_adherent_type = t.rowid";
1081
		if ($rowid) $sql.= " AND d.rowid=".$rowid;
1082
		elseif ($ref || $fk_soc) {
1083
			$sql.= " AND d.entity IN (".getEntity('adherent').")";
1084
			if ($ref) $sql.= " AND d.rowid='".$this->db->escape($ref)."'";
1085
			elseif ($fk_soc > 0) $sql.= " AND d.fk_soc=".$fk_soc;
1086
		}
1087
		elseif ($ref_ext)
1088
		{
1089
			$sql.= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
1090
		}
1091
1092
		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1093
		$resql=$this->db->query($sql);
1094
		if ($resql)
1095
		{
1096
			if ($this->db->num_rows($resql))
1097
			{
1098
				$obj = $this->db->fetch_object($resql);
1099
1100
				$this->entity			= $obj->entity;
1101
				$this->ref				= $obj->rowid;
1102
				$this->id				= $obj->rowid;
1103
				$this->ref_ext			= $obj->ref_ext;
1104
				$this->civility_id		= $obj->civility_id;
1105
				$this->firstname		= $obj->firstname;
1106
				$this->lastname			= $obj->lastname;
1107
				$this->login			= $obj->login;
1108
				$this->societe			= $obj->company;
1109
				$this->company			= $obj->company;
1110
				$this->fk_soc			= $obj->fk_soc;
1111
				$this->address			= $obj->address;
1112
				$this->zip				= $obj->zip;
1113
				$this->town				= $obj->town;
1114
1115
				$this->pass				= $obj->pass;
1116
				$this->pass_indatabase  = $obj->pass;
1117
				$this->pass_indatabase_crypted = $obj->pass_crypted;
1118
1119
				$this->state_id			= $obj->state_id;
1120
				$this->state_code		= $obj->state_id?$obj->state_code:'';
1121
				$this->state			= $obj->state_id?$obj->state:'';
1122
1123
				$this->country_id		= $obj->country_id;
1124
				$this->country_code		= $obj->country_code;
1125
				if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code)
1126
					$this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
1127
				else
1128
					$this->country=$obj->country;
1129
1130
				$this->phone			= $obj->phone;
1131
				$this->phone_perso		= $obj->phone_perso;
1132
				$this->phone_mobile		= $obj->phone_mobile;
1133
				$this->email			= $obj->email;
1134
				$this->skype			= $obj->skype;
1135
1136
				$this->photo			= $obj->photo;
1137
				$this->statut			= $obj->statut;
1138
				$this->public			= $obj->public;
1139
1140
				$this->datec			= $this->db->jdate($obj->datec);
1141
				$this->datem			= $this->db->jdate($obj->datem);
1142
				$this->datefin			= $this->db->jdate($obj->datefin);
1143
				$this->datevalid		= $this->db->jdate($obj->datev);
1144
				$this->birth			= $this->db->jdate($obj->birthday);
1145
1146
				$this->note_private		= $obj->note_private;
1147
				$this->note_public		= $obj->note_public;
1148
				$this->morphy			= $obj->morphy;
1149
1150
				$this->typeid			= $obj->fk_adherent_type;
1151
				$this->type				= $obj->type;
1152
				$this->need_subscription 	= $obj->subscription;
1153
1154
				$this->user_id			= $obj->user_id;
1155
				$this->user_login		= $obj->user_login;
1156
1157
				$this->model_pdf        = $obj->model_pdf;
1158
1159
				// Retreive all extrafield
1160
				// fetch optionals attributes and labels
1161
				$this->fetch_optionals();
1162
1163
				// Load other properties
1164
				$result=$this->fetch_subscriptions();
1165
1166
				return $this->id;
1167
			}
1168
			else
1169
			{
1170
				return 0;
1171
			}
1172
		}
1173
		else
1174
		{
1175
			$this->error=$this->db->lasterror();
1176
			return -1;
1177
		}
1178
	}
1179
1180
1181
	/**
1182
	 *	Fonction qui recupere pour un adherent les parametres
1183
	 *				first_subscription_date
1184
	 *				first_subscription_amount
1185
	 *				last_subscription_date
1186
	 *				last_subscription_amount
1187
	 *
1188
	 *	@return		int			<0 si KO, >0 si OK
1189
	 */
1190
	function fetch_subscriptions()
1191
	{
1192
		global $langs;
1193
1194
		require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1195
1196
		$sql = "SELECT c.rowid, c.fk_adherent, c.subscription, c.note, c.fk_bank,";
1197
		$sql.= " c.tms as datem,";
1198
		$sql.= " c.datec as datec,";
1199
		$sql.= " c.dateadh as dateh,";
1200
		$sql.= " c.datef as datef";
1201
		$sql.= " FROM ".MAIN_DB_PREFIX."subscription as c";
1202
		$sql.= " WHERE c.fk_adherent = ".$this->id;
1203
		$sql.= " ORDER BY c.dateadh";
1204
		dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
1205
1206
		$resql=$this->db->query($sql);
1207
		if ($resql)
1208
		{
1209
			$this->subscriptions=array();
1210
1211
			$i=0;
1212
			while ($obj = $this->db->fetch_object($resql))
1213
			{
1214
				if ($i==0)
1215
				{
1216
					$this->first_subscription_date=$obj->dateh;
1217
					$this->first_subscription_amount=$obj->subscription;
1218
				}
1219
				$this->last_subscription_date=$obj->dateh;
1220
				$this->last_subscription_amount=$obj->subscription;
1221
1222
				$subscription=new Subscription($this->db);
1223
				$subscription->id=$obj->rowid;
1224
				$subscription->fk_adherent=$obj->fk_adherent;
1225
				$subscription->amount=$obj->subscription;
1226
				$subscription->note=$obj->note;
1227
				$subscription->fk_bank=$obj->fk_bank;
1228
				$subscription->datem=$this->db->jdate($obj->datem);
1229
				$subscription->datec=$this->db->jdate($obj->datec);
1230
				$subscription->dateh=$this->db->jdate($obj->dateh);
1231
				$subscription->datef=$this->db->jdate($obj->datef);
1232
1233
				$this->subscriptions[]=$subscription;
1234
1235
				$i++;
1236
			}
1237
			return 1;
1238
		}
1239
		else
1240
		{
1241
			$this->error=$this->db->error().' sql='.$sql;
1242
			return -1;
1243
		}
1244
	}
1245
1246
1247
	/**
1248
	 *	Insert subscription into database and eventually add links to banks, mailman, etc...
1249
	 *
1250
	 *	@param	int	        $date        		Date of effect of subscription
1251
	 *	@param	double		$amount     		Amount of subscription (0 accepted for some members)
1252
	 *	@param	int			$accountid			Id bank account
1253
	 *	@param	string		$operation			Type of payment (if Id bank account provided). Example: 'CB', ...
1254
	 *	@param	string		$label				Label operation (if Id bank account provided)
1255
	 *	@param	string		$num_chq			Numero cheque (if Id bank account provided)
1256
	 *	@param	string		$emetteur_nom		Name of cheque writer
1257
	 *	@param	string		$emetteur_banque	Name of bank of cheque
1258
	 *	@param	int     	$datesubend			Date end subscription
1259
	 *	@return int         					rowid of record added, <0 if KO
1260
	 */
1261
	function subscription($date, $amount, $accountid=0, $operation='', $label='', $num_chq='', $emetteur_nom='', $emetteur_banque='', $datesubend=0)
1262
	{
1263
		global $conf,$langs,$user;
1264
1265
		require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1266
1267
		$error=0;
1268
1269
		// Clean parameters
1270
		if (! $amount) $amount=0;
1271
1272
		$this->db->begin();
1273
1274
		if ($datesubend)
1275
		{
1276
			$datefin=$datesubend;
1277
		}
1278
		else
1279
		{
1280
			// If no end date, end date = date + 1 year - 1 day
1281
			$datefin = dol_time_plus_duree($date,1,'y');
1282
			$datefin = dol_time_plus_duree($datefin,-1,'d');
1283
		}
1284
1285
		// Create subscription
1286
		$subscription=new Subscription($this->db);
1287
		$subscription->fk_adherent=$this->id;
1288
		$subscription->dateh=$date;		// Date of new subscription
1289
		$subscription->datef=$datefin;	// End data of new subscription
1290
		$subscription->amount=$amount;
1291
		$subscription->note=$label;		// deprecated
1292
		$subscription->note_public=$label;
1293
1294
		$rowid=$subscription->create($user);
1295
		if ($rowid > 0)
1296
		{
1297
			// Update denormalized subscription end date (read database subscription to find values)
1298
			// This will also update this->datefin
1299
			$result=$this->update_end_date($user);
1300
			if ($result > 0)
1301
			{
1302
				// Change properties of object (used by triggers)
1303
				$this->last_subscription_date=dol_now();
1304
				$this->last_subscription_amount=$amount;
1305
				$this->last_subscription_date_start=$date;
1306
				$this->last_subscription_date_end=$datefin;
1307
			}
1308
1309
			if (! $error)
1310
			{
1311
				$this->db->commit();
1312
				return $rowid;
1313
			}
1314
			else
1315
			{
1316
				$this->db->rollback();
1317
				return -2;
1318
			}
1319
		}
1320
		else
1321
		{
1322
			$this->error=$subscription->error;
1323
			$this->errors=$subscription->errors;
1324
			$this->db->rollback();
1325
			return -1;
1326
		}
1327
	}
1328
1329
1330
	/**
1331
	 *	Do complementary actions after subscription recording.
1332
	 *
1333
	 *	@param	int			$subscriptionid			Id of created subscription
1334
	 *  @param	string		$option					Which action ('bankdirect', 'invoiceonly', ...)
1335
	 *	@param	int			$accountid				Id bank account
1336
	 *	@param	int			$datesubscription		Date of subscription
1337
	 *	@param	int			$paymentdate			Date of payment
1338
	 *	@param	string		$operation				Code of type of operation (if Id bank account provided). Example 'CB', ...
1339
	 *	@param	string		$label					Label operation (if Id bank account provided)
1340
	 *	@param	double		$amount     			Amount of subscription (0 accepted for some members)
1341
	 *	@param	string		$num_chq				Numero cheque (if Id bank account provided)
1342
	 *	@param	string		$emetteur_nom			Name of cheque writer
1343
	 *	@param	string		$emetteur_banque		Name of bank of cheque
1344
	 *  @param	string		$autocreatethirdparty	Auto create new thirdparty if member not linked to a thirdparty.
1345
	 *	@return int									<0 if KO, >0 if OK
1346
	 */
1347
	function subscriptionComplementaryActions($subscriptionid, $option, $accountid, $datesubscription, $paymentdate, $operation, $label, $amount, $num_chq, $emetteur_nom='', $emetteur_banque='', $autocreatethirdparty=0)
1348
	{
1349
		global $conf, $langs, $user, $mysoc;
1350
1351
		$error = 0;
1352
1353
		$this->invoice = null;	// This will contains invoice if an invoice is created
1354
1355
		// Insert into bank account directlty (if option choosed for) + link to llx_subscription if option is 'bankdirect'
1356
		if ($option == 'bankdirect' && $accountid)
1357
		{
1358
			require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1359
1360
			$acct=new Account($this->db);
1361
			$result=$acct->fetch($accountid);
1362
1363
			$dateop=$paymentdate;
1364
1365
			$insertid=$acct->addline($dateop, $operation, $label, $amount, $num_chq, '', $user, $emetteur_nom, $emetteur_banque);
1366
			if ($insertid > 0)
1367
			{
1368
				$inserturlid=$acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullname($langs), 'member');
1369
				if ($inserturlid > 0)
1370
				{
1371
					// Update table subscription
1372
					$sql ="UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".$insertid;
1373
					$sql.=" WHERE rowid=".$subscriptionid;
1374
1375
					dol_syslog("subscription::subscription", LOG_DEBUG);
1376
					$resql = $this->db->query($sql);
1377
					if (! $resql)
1378
					{
1379
						$error++;
1380
						$this->error=$this->db->lasterror();
1381
						$this->errors[]=$this->error;
1382
					}
1383
				}
1384
				else
1385
				{
1386
					$error++;
1387
					$this->error=$acct->error;
1388
					$this->errors=$acct->errors;
1389
				}
1390
			}
1391
			else
1392
			{
1393
				$error++;
1394
				$this->error=$acct->error;
1395
				$this->errors=$acct->errors;
1396
			}
1397
		}
1398
1399
		// If option choosed, we create invoice
1400
		if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly')
1401
		{
1402
			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1403
			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
1404
1405
			$invoice=new Facture($this->db);
1406
			$customer=new Societe($this->db);
1407
1408
			if (! $error)
1409
			{
1410
				if (! ($this->fk_soc > 0))
1411
				{
1412
					if ($autocreatethirdparty)
1413
					{
1414
						// Create a linked thirdparty to member
1415
						$companyalias='';
1416
						$fullname = $this->getFullName($langs);
1417
1418
						if ($this->morphy == 'mor')
1419
						{
1420
							$companyname=$this->societe;
1421
							if (! empty($fullname)) $companyalias=$fullname;
1422
						}
1423
						else
1424
						{
1425
							$companyname=$fullname;
1426
							if (! empty($this->societe)) $companyalias=$this->societe;
1427
						}
1428
1429
						$result=$customer->create_from_member($this, $companyname, $companyalias);
1430
						if ($result < 0)
1431
						{
1432
							$this->error = $customer->error;
1433
							$this->errors = $customer->errors;
1434
							$error++;
1435
						}
1436
						else
1437
						{
1438
							$this->fk_soc = $result;
1439
						}
1440
					}
1441
					else
1442
					{
1443
						 $langs->load("errors");
1444
						 $this->error=$langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
1445
						 $this->errors[]=$this->error;
1446
						 $error++;
1447
					}
1448
				}
1449
			}
1450
			if (! $error)
1451
			{
1452
				$result=$customer->fetch($this->fk_soc);
1453
				if ($result <= 0)
1454
				{
1455
					$this->error=$customer->error;
1456
					$this->errors=$customer->errors;
1457
					$error++;
1458
				}
1459
			}
1460
1461
			if (! $error)
1462
			{
1463
				// Create draft invoice
1464
				$invoice->type=Facture::TYPE_STANDARD;
1465
				$invoice->cond_reglement_id=$customer->cond_reglement_id;
1466
				if (empty($invoice->cond_reglement_id))
1467
				{
1468
					$paymenttermstatic=new PaymentTerm($this->db);
1469
					$invoice->cond_reglement_id=$paymenttermstatic->getDefaultId();
1470
					if (empty($invoice->cond_reglement_id))
1471
					{
1472
						$error++;
1473
						$this->error='ErrorNoPaymentTermRECEPFound';
1474
						$this->errors[]=$this->error;
1475
					}
1476
				}
1477
				$invoice->socid=$this->fk_soc;
1478
				$invoice->date=$datesubscription;
1479
1480
				// Possibility to add external linked objects with hooks
1481
				$invoice->linked_objects['subscription'] = $subscriptionid;
1482
				if (! empty($_POST['other_linked_objects']) && is_array($_POST['other_linked_objects']))
1483
				{
1484
					$invoice->linked_objects = array_merge($invoice->linked_objects, $_POST['other_linked_objects']);
1485
				}
1486
1487
				$result=$invoice->create($user);
1488
				if ($result <= 0)
1489
				{
1490
					$this->error=$invoice->error;
1491
					$this->errors=$invoice->errors;
1492
					$error++;
1493
				}
1494
				else
1495
				{
1496
					$this->invoice = $invoice;
1497
				}
1498
			}
1499
1500
			if (! $error)
1501
			{
1502
				// Add line to draft invoice
1503
				$idprodsubscription=0;
1504
				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;
1505
1506
				$vattouse=0;
1507
				if (isset($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) && $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS == 'defaultforfoundationcountry')
1508
				{
1509
					$vattouse=get_default_tva($mysoc, $mysoc, $idprodsubscription);
1510
				}
1511
				//print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
1512
				$result=$invoice->addline($label,0,1,$vattouse,0,0,$idprodsubscription,0,$datesubscription,'',0,0,'','TTC',$amount,1);
1513
				if ($result <= 0)
1514
				{
1515
					$this->error=$invoice->error;
1516
					$this->errors=$invoice->errors;
1517
					$error++;
1518
				}
1519
			}
1520
1521
			if (! $error)
1522
			{
1523
				// Validate invoice
1524
				$result=$invoice->validate($user);
1525
				if ($result <= 0)
1526
				{
1527
					$this->error=$invoice->error;
1528
					$this->errors=$invoice->errors;
1529
					$error++;
1530
				}
1531
			}
1532
1533
			if (! $error)
1534
			{
1535
				// TODO Link invoice with subscription ?
1536
			}
1537
1538
			// Add payment onto invoice
1539
			if (! $error && $option == 'bankviainvoice' && $accountid)
1540
			{
1541
				require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1542
				require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
1543
				require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
1544
1545
				$amounts = array();
1546
				$amounts[$invoice->id] = price2num($amount);
1547
1548
				$paiement = new Paiement($this->db);
1549
				$paiement->datepaye     = $paymentdate;
1550
				$paiement->amounts      = $amounts;
1551
				$paiement->paiementid   = dol_getIdFromCode($this->db,$operation,'c_paiement','code','id',1);
1552
				$paiement->num_paiement = $num_chq;
1553
				$paiement->note         = $label;
1554
				$paiement->note_public  = $label;
1555
1556
				if (! $error)
1557
				{
1558
					// Create payment line for invoice
1559
					$paiement_id = $paiement->create($user);
1560
					if (! $paiement_id > 0)
1561
					{
1562
						$this->error=$paiement->error;
1563
						$this->errors=$paiement->errors;
1564
						$error++;
1565
					}
1566
				}
1567
1568
				if (! $error)
1569
				{
1570
					// Add transaction into bank account
1571
					$bank_line_id=$paiement->addPaymentToBank($user,'payment','(SubscriptionPayment)',$accountid,$emetteur_nom,$emetteur_banque);
1572
					if (! ($bank_line_id > 0))
1573
					{
1574
						$this->error=$paiement->error;
1575
						$this->errors=$paiement->errors;
1576
						$error++;
1577
					}
1578
				}
1579
1580
				if (! $error && !empty($bank_line_id))
1581
				{
1582
					// Update fk_bank into subscription table
1583
					$sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.$bank_line_id;
1584
					$sql.= ' WHERE rowid='.$subscriptionid;
1585
1586
					$result = $this->db->query($sql);
1587
					if (! $result)
1588
					{
1589
						$error++;
1590
					}
1591
				}
1592
1593
				if (! $error)
1594
				{
1595
					// Set invoice as paid
1596
					$invoice->set_paid($user);
1597
				}
1598
			}
1599
1600
			if (! $error)
1601
			{
1602
				// Define output language
1603
				$outputlangs = $langs;
1604
				$newlang = '';
1605
				$lang_id=GETPOST('lang_id');
1606
				if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($lang_id))
1607
					$newlang = $lang_id;
1608
				if ($conf->global->MAIN_MULTILANGS && empty($newlang))
1609
					$newlang = $customer->default_lang;
1610
				if (! empty($newlang)) {
1611
					$outputlangs = new Translate("", $conf);
1612
					$outputlangs->setDefaultLang($newlang);
1613
				}
1614
				// Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
1615
				//if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
1616
1617
				$invoice->generateDocument($invoice->modelpdf, $outputlangs);
1618
			}
1619
		}
1620
1621
		if ($error)
1622
		{
1623
			return -1;
1624
		}
1625
		else
1626
		{
1627
			return 1;
1628
		}
1629
	}
1630
1631
1632
	/**
1633
	 *		Function that validate a member
1634
	 *
1635
	 *		@param	User	$user		user adherent qui valide
1636
	 *		@return	int					<0 if KO, 0 if nothing done, >0 if OK
1637
	 */
1638
	function validate($user)
1639
	{
1640
		global $langs,$conf;
1641
1642
		$error=0;
1643
		$now=dol_now();
1644
1645
		// Check parameters
1646
		if ($this->statut == 1)
1647
		{
1648
			dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
1649
			return 0;
1650
		}
1651
1652
		$this->db->begin();
1653
1654
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1655
		$sql.= " statut = 1";
1656
		$sql.= ", datevalid = '".$this->db->idate($now)."'";
1657
		$sql.= ", fk_user_valid=".$user->id;
1658
		$sql.= " WHERE rowid = ".$this->id;
1659
1660
		dol_syslog(get_class($this)."::validate", LOG_DEBUG);
1661
		$result = $this->db->query($sql);
1662
		if ($result)
1663
		{
1664
			$this->statut=1;
1665
1666
			// Call trigger
1667
			$result=$this->call_trigger('MEMBER_VALIDATE',$user);
1668
			if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1669
			// End call triggers
1670
1671
			$this->db->commit();
1672
			return 1;
1673
		}
1674
		else
1675
		{
1676
			$this->error=$this->db->error();
1677
			$this->db->rollback();
1678
			return -1;
1679
		}
1680
	}
1681
1682
1683
	/**
1684
	 *		Fonction qui resilie un adherent
1685
	 *
1686
	 *		@param	User	$user		User making change
1687
	 *		@return	int					<0 if KO, >0 if OK
1688
	 */
1689
	function resiliate($user)
1690
	{
1691
		global $langs,$conf;
1692
1693
		$error=0;
1694
1695
		// Check paramaters
1696
		if ($this->statut == 0)
1697
		{
1698
			dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
1699
			return 0;
1700
		}
1701
1702
		$this->db->begin();
1703
1704
		$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
1705
		$sql.= " statut = 0";
1706
		$sql.= ", fk_user_valid=".$user->id;
1707
		$sql.= " WHERE rowid = ".$this->id;
1708
1709
		$result = $this->db->query($sql);
1710
		if ($result)
1711
		{
1712
			$this->statut=0;
1713
1714
			// Call trigger
1715
			$result=$this->call_trigger('MEMBER_RESILIATE',$user);
1716
			if ($result < 0) { $error++; $this->db->rollback(); return -1; }
1717
			// End call triggers
1718
1719
			$this->db->commit();
1720
			return 1;
1721
		}
1722
		else
1723
		{
1724
			$this->error=$this->db->error();
1725
			$this->db->rollback();
1726
			return -1;
1727
		}
1728
	}
1729
1730
1731
	/**
1732
	 *  Function to add member into external tools mailing-list, spip, etc.
1733
	 *
1734
	 *  @return		int		<0 if KO, >0 if OK
1735
	 */
1736
	function add_to_abo()
1737
	{
1738
		global $conf,$langs;
1739
1740
		include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
1741
		$mailmanspip=new MailmanSpip($this->db);
1742
1743
		$err=0;
1744
1745
		// mailman
1746
		if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled))
1747
		{
1748
			$result=$mailmanspip->add_to_mailman($this);
1749
1750
			if ($result < 0)
1751
			{
1752
				if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
1753
				$err+=1;
1754
			}
1755
			foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail)
1756
			{
1757
				$langs->load("errors");
1758
				$this->errors[]=$langs->trans("ErrorFailedToAddToMailmanList",$tmpemail,$tmplist);
1759
			}
1760
			foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail)
1761
			{
1762
				$langs->load("mailmanspip");
1763
				$this->mesgs[]=$langs->trans("SuccessToAddToMailmanList",$tmpemail,$tmplist);
1764
			}
1765
		}
1766
1767
		// spip
1768
		if (! empty($conf->global->ADHERENT_USE_SPIP) && ! empty($conf->mailmanspip->enabled))
1769
		{
1770
			$result=$mailmanspip->add_to_spip($this);
1771
			if ($result < 0)
1772
			{
1773
				$this->errors[]=$mailmanspip->error;
1774
				$err+=1;
1775
			}
1776
		}
1777
		if ($err)
1778
		{
1779
			return -$err;
1780
		}
1781
		else
1782
		{
1783
			return 1;
1784
		}
1785
	}
1786
1787
1788
	/**
1789
	 *  Function to delete a member from external tools like mailing-list, spip, etc.
1790
	 *
1791
	 *  @return     int     <0 if KO, >0 if OK
1792
	 */
1793
	function del_to_abo()
1794
	{
1795
		global $conf,$langs;
1796
1797
		include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
1798
		$mailmanspip=new MailmanSpip($this->db);
1799
1800
		$err=0;
1801
1802
		// mailman
1803
		if (! empty($conf->global->ADHERENT_USE_MAILMAN))
1804
		{
1805
			$result=$mailmanspip->del_to_mailman($this);
1806
			if ($result < 0)
1807
			{
1808
				if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
1809
				$err+=1;
1810
			}
1811
1812
			foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail)
1813
			{
1814
				$langs->load("errors");
1815
				$this->errors[]=$langs->trans("ErrorFailedToRemoveToMailmanList",$tmpemail,$tmplist);
1816
			}
1817
			foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail)
1818
			{
1819
				$langs->load("mailmanspip");
1820
				$this->mesgs[]=$langs->trans("SuccessToRemoveToMailmanList",$tmpemail,$tmplist);
1821
			}
1822
		}
1823
1824
		if ($conf->global->ADHERENT_USE_SPIP && ! empty($conf->mailmanspip->enabled))
1825
		{
1826
			$result=$mailmanspip->del_to_spip($this);
1827
			if ($result < 0)
1828
			{
1829
				$this->errors[]=$mailmanspip->error;
1830
				$err+=1;
1831
			}
1832
		}
1833
		if ($err)
1834
		{
1835
			// error
1836
			return -$err;
1837
		}
1838
		else
1839
		{
1840
			return 1;
1841
		}
1842
	}
1843
1844
1845
	/**
1846
	 *    Return civility label of a member
1847
	 *
1848
	 *    @return   string              	Translated name of civility (translated with transnoentitiesnoconv)
1849
	 */
1850
	function getCivilityLabel()
1851
	{
1852
		global $langs;
1853
		$langs->load("dict");
1854
1855
		$code=(empty($this->civility_id)?'':$this->civility_id);
1856
		if (empty($code)) return '';
1857
		return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
1858
	}
1859
1860
	/**
1861
	 *  Return clicable name (with picto eventually)
1862
	 *
1863
	 *	@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)
1864
	 *	@param	int		$maxlen						length max label
1865
	 *	@param	string	$option						Page for link ('card', 'category', 'subscription', ...)
1866
	 *  @param  string  $mode           			''=Show firstname+lastname as label (using default order), 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref
1867
	 *  @param  string  $morecss        			Add more css on link
1868
	 *  @param  int     $save_lastsearch_value    	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
1869
	 *	@return	string								Chaine avec URL
1870
	 */
1871
	function getNomUrl($withpictoimg=0, $maxlen=0, $option='card', $mode='', $morecss='', $save_lastsearch_value=-1)
1872
	{
1873
		global $conf, $langs;
1874
1875
		if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
1876
1877
		$notooltip=0;
1878
1879
		$result=''; $label='';
1880
		$link=''; $linkstart=''; $linkend='';
1881
1882
		if (! empty($this->photo))
1883
		{
1884
			$label.= '<div class="photointooltip">';
1885
			$label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1);
1886
			$label.= '</div><div style="clear: both;"></div>';
1887
		}
1888
1889
		$label.= '<div class="centpercent">';
1890
		$label.= '<u>' . $langs->trans("Member") . '</u>';
1891
		if (! empty($this->ref))
1892
			$label.= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
1893
		if (! empty($this->firstname) || ! empty($this->lastname))
1894
			$label.= '<br><b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs);
1895
		$label.='</div>';
1896
1897
		$url = DOL_URL_ROOT.'/adherents/card.php?rowid='.$this->id;
1898
		if ($option == 'subscription')
1899
		{
1900
			$url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.$this->id;
1901
		}
1902
1903
		if ($option != 'nolink')
1904
		{
1905
			// Add param to save lastsearch_values or not
1906
			$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
1907
			if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
1908
			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
1909
		}
1910
1911
		$link = '<a href="'.$url.'"';
1912
		$linkclose="";
1913
		if (empty($notooltip))
1914
		{
1915
			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
1916
			{
1917
				$langs->load("users");
1918
				$label=$langs->trans("ShowUser");
1919
				$linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
1920
			}
1921
			$linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
1922
			$linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
1923
		}
1924
1925
		$link.=$linkclose.'>';
1926
		$linkend='</a>';
1927
1928
		//if ($withpictoimg == -1) $result.='<div class="nowrap">';
1929
		$result.=$link;
1930
		if ($withpictoimg)
1931
		{
1932
			$paddafterimage='';
1933
			if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"';
1934
			// Only picto
1935
			if ($withpictoimg > 0) $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>';
1936
			// Picto must be a photo
1937
			else $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>';
1938
			$result.=$picto;
1939
		}
1940
		if ($withpictoimg > -2 && $withpictoimg != 2)
1941
		{
1942
			if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<div class="inline-block nopadding valignmiddle'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' usertext'.$morecss:'').'">';
1943
			if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen);
1944
			elseif ($mode == 'ref') $result.=$this->id;
1945
			else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen);
1946
			if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</div>';
1947
		}
1948
		$result.=$linkend;
1949
		//if ($withpictoimg == -1) $result.='</div>';
1950
1951
		return $result;
1952
	}
1953
1954
	/**
1955
	 *  Retourne le libelle du statut d'un adherent (brouillon, valide, resilie)
1956
	 *
1957
	 *  @param	int		$mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
1958
	 *  @return string				Label
1959
	 */
1960
	function getLibStatut($mode=0)
1961
	{
1962
		return $this->LibStatut($this->statut,$this->need_subscription,$this->datefin,$mode);
1963
	}
1964
1965
	/**
1966
	 *  Renvoi le libelle d'un statut donne
1967
	 *
1968
	 *  @param	int			$statut      			Id statut
1969
	 *	@param	int			$need_subscription		1 if member type need subscription, 0 otherwise
1970
	 *	@param	int     	$date_end_subscription	Date fin adhesion
1971
	 *  @param  int			$mode        			0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
1972
	 *  @return string      						Label
1973
	 */
1974
	function LibStatut($statut,$need_subscription,$date_end_subscription,$mode=0)
1975
	{
1976
		global $langs;
1977
		$langs->load("members");
1978
		if ($mode == 0)
1979
		{
1980
			if ($statut == -1) return $langs->trans("MemberStatusDraft");
1981
			if ($statut >= 1)
1982
			{
1983
				if (! $date_end_subscription)            return $langs->trans("MemberStatusActive");
1984
				elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate");
1985
				else                                     return $langs->trans("MemberStatusPaid");
1986
			}
1987
			if ($statut == 0)  return $langs->trans("MemberStatusResiliated");
1988
		}
1989
		if ($mode == 1)
1990
		{
1991
			if ($statut == -1) return $langs->trans("MemberStatusDraftShort");
1992
			if ($statut >= 1)
1993
			{
1994
				if (! $date_end_subscription)            return $langs->trans("MemberStatusActiveShort");
1995
				elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLateShort");
1996
				else                                     return $langs->trans("MemberStatusPaidShort");
1997
			}
1998
			if ($statut == 0)  return $langs->trans("MemberStatusResiliatedShort");
1999
		}
2000
		if ($mode == 2)
2001
		{
2002
			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraftShort");
2003
			if ($statut >= 1)
2004
			{
2005
				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActiveShort");
2006
				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLateShort");
2007
				else                                     return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaidShort");
2008
			}
2009
			if ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliatedShort");
2010
		}
2011
		if ($mode == 3)
2012
		{
2013
			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0');
2014
			if ($statut >= 1)
2015
			{
2016
				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'),'statut1');
2017
				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
2018
				else                                     return img_picto($langs->trans('MemberStatusPaid'),'statut4');
2019
			}
2020
			if ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5');
2021
		}
2022
		if ($mode == 4)
2023
		{
2024
			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraft");
2025
			if ($statut >= 1)
2026
			{
2027
				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActive");
2028
				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLate");
2029
				else                                     return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaid");
2030
			}
2031
			if ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliated");
2032
		}
2033
		if ($mode == 5)
2034
		{
2035
			if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
2036
			if ($statut >= 1)
2037
			{
2038
				if (! $date_end_subscription)            return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveShort").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
2039
				elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLateShort").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
2040
				else                                     return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaidShort").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
2041
			}
2042
			if ($statut == 0)  return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5');
2043
		}
2044
		if ($mode == 6)
2045
		{
2046
			if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
2047
			if ($statut >= 1)
2048
			{
2049
				if (! $date_end_subscription)            return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActive").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
2050
				elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLate").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
2051
				else                                     return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaid").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
2052
			}
2053
			if ($statut == 0)  return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5');
2054
		}
2055
	}
2056
2057
2058
	/**
2059
	 *      Charge indicateurs this->nb de tableau de bord
2060
	 *
2061
	 *      @return     int         <0 if KO, >0 if OK
2062
	 */
2063
	function load_state_board()
2064
	{
2065
		global $conf;
2066
2067
		$this->nb=array();
2068
2069
		$sql = "SELECT count(a.rowid) as nb";
2070
		$sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
2071
		$sql.= " WHERE a.statut > 0";
2072
		$sql.= " AND a.entity IN (".getEntity('adherent').")";
2073
2074
		$resql=$this->db->query($sql);
2075
		if ($resql)
2076
		{
2077
			while ($obj=$this->db->fetch_object($resql))
2078
			{
2079
				$this->nb["members"]=$obj->nb;
2080
			}
2081
			$this->db->free($resql);
2082
			return 1;
2083
		}
2084
		else
2085
		{
2086
			dol_print_error($this->db);
2087
			$this->error=$this->db->error();
2088
			return -1;
2089
		}
2090
2091
	}
2092
2093
	/**
2094
	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
2095
	 *
2096
	 *      @param	User	$user   		Objet user
2097
	 *      @return WorkboardResponse|int 	<0 if KO, WorkboardResponse if OK
2098
	 */
2099
	function load_board($user)
2100
	{
2101
		global $conf, $langs;
2102
2103
		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
2104
2105
		$now=dol_now();
2106
2107
		$sql = "SELECT a.rowid, a.datefin, a.statut";
2108
		$sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
2109
		$sql.= " WHERE a.statut = 1";
2110
		$sql.= " AND a.entity IN (".getEntity('adherent').")";
2111
		$sql.= " AND (a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."')";
2112
2113
		$resql=$this->db->query($sql);
2114
		if ($resql)
2115
		{
2116
			$langs->load("members");
2117
2118
			$response = new WorkboardResponse();
2119
			$response->warning_delay=$conf->adherent->subscription->warning_delay/60/60/24;
2120
			$response->label=$langs->trans("MembersWithSubscriptionToReceive");
2121
			$response->url=DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut=1&amp;filter=outofdate';
2122
			$response->img=img_object('',"user");
2123
2124
			$adherentstatic = new Adherent($this->db);
2125
2126
			while ($obj=$this->db->fetch_object($resql))
2127
			{
2128
				$response->nbtodo++;
2129
2130
				$adherentstatic->datefin = $this->db->jdate($obj->datefin);
2131
				$adherentstatic->statut = $obj->statut;
2132
2133
				if ($adherentstatic->hasDelay()) {
2134
					$response->nbtodolate++;
2135
				}
2136
			}
2137
2138
			return $response;
2139
		}
2140
		else
2141
		{
2142
			dol_print_error($this->db);
2143
			$this->error=$this->db->error();
2144
			return -1;
2145
		}
2146
	}
2147
2148
2149
	/**
2150
	 *  Create a document onto disk according to template module.
2151
	 *
2152
	 *  @param	    string		$modele			Force template to use ('' to not force)
2153
	 *  @param		Translate	$outputlangs	objet lang a utiliser pour traduction
2154
	 *  @param      int			$hidedetails    Hide details of lines
2155
	 *  @param      int			$hidedesc       Hide description
2156
	 *  @param      int			$hideref        Hide ref
2157
	 *  @return     int         				0 if KO, 1 if OK
2158
	 */
2159
	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
2160
	{
2161
		global $conf,$langs;
2162
2163
		$langs->load("orders");
2164
2165
		if (! dol_strlen($modele)) {
2166
2167
			$modele = 'standard';
2168
2169
			if ($this->modelpdf) {
2170
				$modele = $this->modelpdf;
2171
			} elseif (! empty($conf->global->ADHERENT_ADDON_PDF)) {
2172
				$modele = $conf->global->ADHERENT_ADDON_PDF;
2173
			}
2174
		}
2175
2176
		$modelpath = "core/modules/member/doc/";
2177
2178
		return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
2179
	}
2180
2181
2182
	/**
2183
	 *  Initialise an instance with random values.
2184
	 *  Used to build previews or test instances.
2185
	 *	id must be 0 if object instance is a specimen.
2186
	 *
2187
	 *  @return	void
2188
	 */
2189
	function initAsSpecimen()
2190
	{
2191
		global $user,$langs;
2192
2193
		// Initialise parametres
2194
		$this->id=0;
2195
		$this->specimen=1;
2196
		$this->civility_id = 0;
2197
		$this->lastname = 'DOLIBARR';
2198
		$this->firstname = 'SPECIMEN';
2199
		$this->login='dolibspec';
2200
		$this->pass='dolibspec';
2201
		$this->societe = 'Societe ABC';
2202
		$this->address = '61 jump street';
2203
		$this->zip = '75000';
2204
		$this->town = 'Paris';
2205
		$this->country_id = 1;
2206
		$this->country_code = 'FR';
2207
		$this->country = 'France';
2208
		$this->morphy = 1;
2209
		$this->email = '[email protected]';
2210
		$this->skype = 'tom.hanson';
2211
		$this->phone        = '0999999999';
2212
		$this->phone_perso  = '0999999998';
2213
		$this->phone_mobile = '0999999997';
2214
		$this->note_private='No comment';
2215
		$this->birth=time();
2216
		$this->photo='';
2217
		$this->public=1;
2218
		$this->statut=0;
2219
2220
		$this->datefin=time();
2221
		$this->datevalid=time();
2222
2223
		$this->typeid=1;				// Id type adherent
2224
		$this->type='Type adherent';	// Libelle type adherent
2225
		$this->need_subscription=0;
2226
2227
		$this->first_subscription_date=time();
2228
		$this->first_subscription_amount=10;
2229
		$this->last_subscription_date=time();
2230
		$this->last_subscription_amount=10;
2231
	}
2232
2233
2234
	/**
2235
	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
2236
	 *
2237
	 *	@param	array	$info		Info array loaded by _load_ldap_info
2238
	 *	@param	int		$mode		0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
2239
	 *								1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
2240
	 *								2=Return key only (uid=qqq)
2241
	 *	@return	string				DN
2242
	 */
2243
	function _load_ldap_dn($info,$mode=0)
2244
	{
2245
		global $conf;
2246
		$dn='';
2247
		if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS].",".$conf->global->LDAP_MEMBER_DN;
2248
		if ($mode==1) $dn=$conf->global->LDAP_MEMBER_DN;
2249
		if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS];
2250
		return $dn;
2251
	}
2252
2253
2254
	/**
2255
	 *	Initialise tableau info (tableau des attributs LDAP)
2256
	 *
2257
	 *	@return		array		Tableau info des attributs
2258
	 */
2259
	function _load_ldap_info()
2260
	{
2261
		global $conf,$langs;
2262
2263
		$info=array();
2264
		$keymodified=false;
2265
2266
		// Object classes
2267
		$info["objectclass"]=explode(',',$conf->global->LDAP_MEMBER_OBJECT_CLASS);
2268
2269
		$this->fullname=$this->getFullName($langs);
2270
2271
		// For avoid ldap error when firstname and lastname are empty
2272
		if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->societe)) {
2273
			$this->fullname = $this->societe;
2274
			$this->lastname = $this->societe;
2275
		}
2276
2277
		// Possible LDAP KEY (constname => varname)
2278
		$ldapkey = array(
2279
			'LDAP_MEMBER_FIELD_FULLNAME'		=> 'fullname',
2280
			'LDAP_MEMBER_FIELD_NAME'			=> 'lastname',
2281
			'LDAP_MEMBER_FIELD_LOGIN'		=> 'login',
2282
			'LDAP_MEMBER_FIELD_LOGIN_SAMBA'	=> 'login',
2283
			'LDAP_MEMBER_FIELD_MAIL'			=> 'email'
2284
		);
2285
2286
		// Member
2287
		foreach ($ldapkey as $constname => $varname)
2288
		{
2289
			if (! empty($this->$varname) && ! empty($conf->global->$constname))
2290
			{
2291
				$info[$conf->global->$constname] = $this->$varname;
2292
2293
				// Check if it is the LDAP key and if its value has been changed
2294
				if (! empty($conf->global->LDAP_KEY_MEMBERS) && $conf->global->LDAP_KEY_MEMBERS == $conf->global->$constname)
2295
				{
2296
					if (! empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) $keymodified=true; // For check if LDAP key has been modified
2297
				}
2298
			}
2299
		}
2300
		if ($this->firstname && ! empty($conf->global->LDAP_MEMBER_FIELD_FIRSTNAME))			$info[$conf->global->LDAP_MEMBER_FIELD_FIRSTNAME] = $this->firstname;
2301
		if ($this->poste && ! empty($conf->global->LDAP_MEMBER_FIELD_TITLE))					$info[$conf->global->LDAP_MEMBER_FIELD_TITLE] = $this->poste;
2302
		if ($this->societe && ! empty($conf->global->LDAP_MEMBER_FIELD_COMPANY))				$info[$conf->global->LDAP_MEMBER_FIELD_COMPANY] = $this->societe;
2303
		if ($this->address && ! empty($conf->global->LDAP_MEMBER_FIELD_ADDRESS))				$info[$conf->global->LDAP_MEMBER_FIELD_ADDRESS] = $this->address;
2304
		if ($this->zip && ! empty($conf->global->LDAP_MEMBER_FIELD_ZIP))						$info[$conf->global->LDAP_MEMBER_FIELD_ZIP] = $this->zip;
2305
		if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN))					$info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town;
2306
		if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY))			$info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code;
2307
		if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE))					$info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype;
2308
		if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE))					$info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone;
2309
		if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO))		$info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso;
2310
		if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE))			$info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile;
2311
		if ($this->fax && ! empty($conf->global->LDAP_MEMBER_FIELD_FAX))						$info[$conf->global->LDAP_MEMBER_FIELD_FAX] = $this->fax;
2312
		if ($this->note_private && ! empty($conf->global->LDAP_MEMBER_FIELD_DESCRIPTION))		$info[$conf->global->LDAP_MEMBER_FIELD_DESCRIPTION] = $this->note_private;
2313
		if ($this->note_public && ! empty($conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC))		$info[$conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC] = $this->note_public;
2314
		if ($this->birth && ! empty($conf->global->LDAP_MEMBER_FIELD_BIRTHDATE))				$info[$conf->global->LDAP_MEMBER_FIELD_BIRTHDATE] = dol_print_date($this->birth,'dayhourldap');
2315
		if (isset($this->statut) && ! empty($conf->global->LDAP_FIELD_MEMBER_STATUS))			$info[$conf->global->LDAP_FIELD_MEMBER_STATUS] = $this->statut;
2316
		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');
2317
2318
		// When password is modified
2319
		if (! empty($this->pass))
2320
		{
2321
			if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD))				$info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass;	// this->pass = mot de passe non crypte
2322
			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)
2323
		}
2324
		// Set LDAP password if possible
2325
		else if ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
2326
		{
2327
			if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
2328
			{
2329
				// Just for the default MD5 !
2330
				if (empty($conf->global->MAIN_SECURITY_HASH_ALGO))
2331
				{
2332
					if ($this->pass_indatabase_crypted && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED))	{
2333
						// Create OpenLDAP MD5 password from Dolibarr MD5 password
2334
						// Note: This suppose that "pass_indatabase_crypted" is a md5 (guaranted by the previous test if "(empty($conf->global->MAIN_SECURITY_HASH_ALGO))"
2335
						$info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = '{md5}'.base64_encode(hex2bin($this->pass_indatabase_crypted));
2336
					}
2337
				}
2338
			}
2339
			// Use $this->pass_indatabase value if exists
2340
			else if (! empty($this->pass_indatabase))
2341
			{
2342
				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
2343
				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
2344
			}
2345
		}
2346
2347
		// Subscriptions
2348
		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');
2349
		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;
2350
		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');
2351
		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;
2352
2353
		return $info;
2354
	}
2355
2356
2357
	/**
2358
	 *      Charge les informations d'ordre info dans l'objet adherent
2359
	 *
2360
	 *      @param  int		$id       Id of member to load
2361
	 *      @return	void
2362
	 */
2363
	function info($id)
2364
	{
2365
		$sql = 'SELECT a.rowid, a.datec as datec,';
2366
		$sql.= ' a.datevalid as datev,';
2367
		$sql.= ' a.tms as datem,';
2368
		$sql.= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
2369
		$sql.= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
2370
		$sql.= ' WHERE a.rowid = '.$id;
2371
2372
		dol_syslog(get_class($this)."::info", LOG_DEBUG);
2373
		$result=$this->db->query($sql);
2374
		if ($result)
2375
		{
2376
			if ($this->db->num_rows($result))
2377
			{
2378
				$obj = $this->db->fetch_object($result);
2379
				$this->id = $obj->rowid;
2380
				if ($obj->fk_user_author)
2381
				{
2382
					$cuser = new User($this->db);
2383
					$cuser->fetch($obj->fk_user_author);
2384
					$this->user_creation   = $cuser;
2385
				}
2386
2387
				if ($obj->fk_user_valid)
2388
				{
2389
					$vuser = new User($this->db);
2390
					$vuser->fetch($obj->fk_user_valid);
2391
					$this->user_validation = $vuser;
2392
				}
2393
2394
				if ($obj->fk_user_mod)
2395
				{
2396
					$muser = new User($this->db);
2397
					$muser->fetch($obj->fk_user_mod);
2398
					$this->user_modification = $muser;
2399
				}
2400
2401
				$this->date_creation     = $this->db->jdate($obj->datec);
2402
				$this->date_validation   = $this->db->jdate($obj->datev);
2403
				$this->date_modification = $this->db->jdate($obj->datem);
2404
			}
2405
2406
			$this->db->free($result);
2407
2408
		}
2409
		else
2410
		{
2411
			dol_print_error($this->db);
2412
		}
2413
	}
2414
2415
	/**
2416
	 * Sets object to supplied categories.
2417
	 *
2418
	 * Deletes object from existing categories not supplied.
2419
	 * Adds it to non existing supplied categories.
2420
	 * Existing categories are left untouch.
2421
	 *
2422
	 * @param int[]|int $categories Category or categories IDs
2423
	 */
2424
	public function setCategories($categories)
2425
	{
2426
		// Handle single category
2427
		if (!is_array($categories)) {
2428
			$categories = array($categories);
2429
		}
2430
2431
		// Get current categories
2432
		require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
2433
		$c = new Categorie($this->db);
2434
		$existing = $c->containing($this->id, Categorie::TYPE_MEMBER, 'id');
2435
2436
		// Diff
2437
		if (is_array($existing)) {
2438
			$to_del = array_diff($existing, $categories);
2439
			$to_add = array_diff($categories, $existing);
2440
		} else {
2441
			$to_del = array(); // Nothing to delete
2442
			$to_add = $categories;
2443
		}
2444
2445
		// Process
2446
		foreach ($to_del as $del) {
2447
			if ($c->fetch($del) > 0) {
2448
				$c->del_type($this, 'member');
2449
			}
2450
		}
2451
		foreach ($to_add as $add) {
2452
			if ($c->fetch($add) > 0) {
2453
				$c->add_type($this, 'member');
2454
			}
2455
		}
2456
2457
		return;
2458
	}
2459
2460
	/**
2461
	 * Function used to replace a thirdparty id with another one.
2462
	 *
2463
	 * @param DoliDB 	$db 			Database handler
2464
	 * @param int 		$origin_id 		Old thirdparty id
2465
	 * @param int 		$dest_id 		New thirdparty id
2466
	 * @return bool
2467
	 */
2468
	public static function replaceThirdparty($db, $origin_id, $dest_id)
2469
	{
2470
		$tables = array(
2471
			'adherent'
2472
		);
2473
2474
		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
2475
	}
2476
2477
	/**
2478
	 * Return if a member is late (subscription late) or not
2479
	 *
2480
	 * @return boolean     True if late, False if not late
2481
	 */
2482
	public function hasDelay()
2483
	{
2484
		global $conf;
2485
2486
		//Only valid members
2487
		if ($this->statut <= 0) return false;
2488
		if (! $this->datefin) return false;
2489
2490
		$now = dol_now();
2491
2492
		return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
2493
	}
2494
2495
2496
2497
2498
	/**
2499
	 * Send reminders by emails before subscription end
2500
	 * CAN BE A CRON TASK
2501
	 *
2502
	 * @param	int			$daysbeforeend		Nb of days before end of subscription (negative number = after subscription)
2503
	 * @return	int								0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
2504
	 */
2505
	public function sendReminderForExpiredSubscription($daysbeforeend=10)
2506
	{
2507
		global $conf, $langs, $mysoc, $user;
2508
2509
		$this->output = '';
2510
		$this->error='';
2511
2512
		$blockingerrormsg = '';
2513
2514
		/*if (empty($conf->global->MEMBER_REMINDER_EMAIL))
2515
		{
2516
			$langs->load("agenda");
2517
			$this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
2518
			return 0;
2519
		}*/
2520
2521
		$now = dol_now();
2522
2523
		dol_syslog(__METHOD__, LOG_DEBUG);
2524
2525
		$tmp=dol_getdate($now);
2526
		$datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year']), -1 * $daysbeforeend, 'd');
2527
2528
		$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
2529
		$sql.= " WHERE datefin = '".$this->db->idate($datetosearchfor)."'";
2530
2531
		$resql = $this->db->query($sql);
2532
		if ($resql)
2533
		{
2534
			$num_rows = $this->db->num_rows($resql);
2535
2536
			include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2537
			$adherent = new Adherent($this->db);
2538
			$formmail=new FormMail($db);
0 ignored issues
show
Bug introduced by
The variable $db does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
2539
2540
			$i=0;
2541
			$nbok = 0;
2542
			$nbko = 0;
2543
			while ($i < $num_rows)
2544
			{
2545
				$obj = $this->db->fetch_object($resql);
2546
2547
				$adherent->fetch($obj->rowid);
2548
2549
				if (empty($adherent->email))
2550
				{
2551
					$nbko++;
2552
				}
2553
				else
2554
				{
2555
					$adherent->fetch_thirdparty();
2556
2557
					// Send reminder email
2558
					include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2559
					include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
2560
2561
					$outputlangs = new Translate('', $conf);
2562
					$outputlangs->setDefaultLang(empty($adherent->thirdparty->default_lang) ? $mysoc->default_lang : $adherent->thirdparty->default_lang);
2563
					$outputlangs->loadLangs(array("main", "members"));
2564
2565
					$arraydefaultmessage=$formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, '(SendReminderForExpiredSubscriptionTitle)');
2566
2567
					if (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0)
2568
					{
2569
						$substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
2570
						//if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
2571
						complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
2572
2573
						$subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
2574
						$msg     = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
2575
						$from = $conf->global->ADHERENT_MAIL_FROM;
2576
						$to = $adherent->email;
2577
2578
						$cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), '', '', 0, 1);
2579
						$result = $cmail->sendfile();
2580
						if (! $result)
2581
						{
2582
							$error++;
0 ignored issues
show
Bug introduced by
The variable $error does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2583
							$this->error = $cmail->error;
2584
							$this->errors += $cmail->errors;
2585
							$nbko++;
2586
						}
2587
						else
2588
						{
2589
							$nbok++;
2590
						}
2591
					}
2592
					else
2593
					{
2594
						$blockingerrormsg="Can't find email template '(SendReminderForExpiredSubscriptionTitle)'";
2595
						$nbko++;
2596
						break;
2597
					}
2598
				}
2599
2600
				$i++;
2601
			}
2602
		}
2603
		else
2604
		{
2605
			$this->error = $this->db->lasterror();
2606
			return 1;
2607
		}
2608
2609
		if ($blockingerrormsg)
2610
		{
2611
			$this->error = $blockingerrormsg;
2612
			return 1;
2613
		}
2614
		else
2615
		{
2616
			$this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
2617
			$this->output.= ' Send successfull to '.$nbok.' members';
2618
			if ($nbko) $this->output.= ' - Canceled for '.$nbko.' member (no email or email sending error)';
2619
		}
2620
2621
		return 0;
2622
	}
2623
2624
}
2625