1<?php
2/* Copyright (C) 2005-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2017	Regis Houssin		<regis.houssin@inodbox.com>
4 * Copyright (C) 2014		Marcos García		<marcosgdf@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20/**
21 *  \file       htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php
22 *  \ingroup    core
23 *  \brief      Fichier de gestion des triggers LDAP
24 */
25
26require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
27
28
29/**
30 *  Class of triggers for ldap module
31 */
32class InterfaceLdapsynchro extends DolibarrTriggers
33{
34	/**
35	 * Constructor
36	 *
37	 * @param DoliDB $db Database handler
38	 */
39	public function __construct($db)
40	{
41		$this->db = $db;
42
43		$this->name = preg_replace('/^Interface/i', '', get_class($this));
44		$this->family = "ldap";
45		$this->description = "Triggers of this module allows to synchronize Dolibarr toward a LDAP database.";
46		// 'development', 'experimental', 'dolibarr' or version
47		$this->version = self::VERSION_DOLIBARR;
48		$this->picto = 'technic';
49	}
50
51	/**
52	 * Function called when a Dolibarrr business event is done.
53	 * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/code/triggers (and declared)
54	 *
55	 * @param string		$action		Event action code
56	 * @param Object		$object     Object
57	 * @param User		    $user       Object user
58	 * @param Translate 	$langs      Object langs
59	 * @param conf		    $conf       Object conf
60	 * @return int         				<0 if KO, 0 if no triggered ran, >0 if OK
61	 */
62	public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
63	{
64		if (empty($conf->ldap->enabled)) return 0; // Module not active, we do nothing
65		if (defined('DISABLE_LDAP_SYNCHRO')) return 0; // If constant defined, we do nothing
66
67		if (!function_exists('ldap_connect')) {
68			dol_syslog("Warning, module LDAP is enabled but LDAP functions not available in this PHP", LOG_WARNING);
69			return 0;
70		}
71
72		require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
73		require_once DOL_DOCUMENT_ROOT."/user/class/usergroup.class.php";
74
75		$result = 0;
76
77		// Users
78		if ($action == 'USER_CREATE') {
79			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
80			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
81				$ldap = new Ldap();
82				$result = $ldap->connect_bind();
83
84				if ($result > 0) {
85					$info = $object->_load_ldap_info();
86					$dn = $object->_load_ldap_dn($info);
87
88					$result = $ldap->add($dn, $info, $user);
89				}
90
91				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
92			}
93		} elseif ($action == 'USER_MODIFY') {
94			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
95			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
96				$ldap = new Ldap();
97				$result = $ldap->connect_bind();
98
99				if ($result > 0) {
100					if (empty($object->oldcopy) || !is_object($object->oldcopy)) {
101						dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING);
102						$object->oldcopy = clone $object;
103					}
104
105					$oldinfo = $object->oldcopy->_load_ldap_info();
106					$olddn = $object->oldcopy->_load_ldap_dn($oldinfo);
107
108					// Verify if entry exist
109					$container = $object->oldcopy->_load_ldap_dn($oldinfo, 1);
110					$search = "(".$object->oldcopy->_load_ldap_dn($oldinfo, 2).")";
111					$records = $ldap->search($container, $search);
112					if (count($records) && $records['count'] == 0) {
113						$olddn = '';
114					}
115
116					$info = $object->_load_ldap_info();
117					$dn = $object->_load_ldap_dn($info);
118					$newrdn = $object->_load_ldap_dn($info, 2);
119					$newparent = $object->_load_ldap_dn($info, 1);
120
121					$result = $ldap->update($dn, $info, $user, $olddn, $newrdn, $newparent);
122
123					if ($result > 0 && !empty($object->context['newgroupid'])) {      // We are in context of adding a new group to user
124						$usergroup = new Usergroup($this->db);
125
126						$usergroup->fetch($object->context['newgroupid']);
127
128						$oldinfo = $usergroup->_load_ldap_info();
129						$olddn = $usergroup->_load_ldap_dn($oldinfo);
130
131						// Verify if entry exist
132						$container = $usergroup->_load_ldap_dn($oldinfo, 1);
133						$search = "(".$usergroup->_load_ldap_dn($oldinfo, 2).")";
134						$records = $ldap->search($container, $search);
135						if (count($records) && $records['count'] == 0)
136						{
137							$olddn = '';
138						}
139
140						$info = $usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call)
141						$dn = $usergroup->_load_ldap_dn($info);
142
143						$result = $ldap->update($dn, $info, $user, $olddn);
144					}
145
146					if ($result > 0 && !empty($object->context['oldgroupid'])) {      // We are in context of removing a group from user
147						$usergroup = new Usergroup($this->db);
148
149						$usergroup->fetch($object->context['oldgroupid']);
150
151						$oldinfo = $usergroup->_load_ldap_info();
152						$olddn = $usergroup->_load_ldap_dn($oldinfo);
153
154						// Verify if entry exist
155						$container = $usergroup->_load_ldap_dn($oldinfo, 1);
156						$search = "(".$usergroup->_load_ldap_dn($oldinfo, 2).")";
157						$records = $ldap->search($container, $search);
158						if (count($records) && $records['count'] == 0)
159						{
160							$olddn = '';
161						}
162
163						$info = $usergroup->_load_ldap_info(); // Contains all members, except the old one (remove already done before trigger call)
164						$dn = $usergroup->_load_ldap_dn($info);
165
166						$result = $ldap->update($dn, $info, $user, $olddn);
167					}
168				}
169
170				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
171			}
172		} elseif ($action == 'USER_NEW_PASSWORD') {
173			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
174			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
175				$ldap = new Ldap();
176				$result = $ldap->connect_bind();
177
178				if ($result > 0) {
179					if (empty($object->oldcopy) || !is_object($object->oldcopy)) {
180						dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING);
181						$object->oldcopy = clone $object;
182					}
183
184					$oldinfo = $object->oldcopy->_load_ldap_info();
185					$olddn = $object->oldcopy->_load_ldap_dn($oldinfo);
186
187					// Verify if entry exist
188					$container = $object->oldcopy->_load_ldap_dn($oldinfo, 1);
189					$search = "(".$object->oldcopy->_load_ldap_dn($oldinfo, 2).")";
190					$records = $ldap->search($container, $search);
191					if (count($records) && $records['count'] == 0) {
192						$olddn = '';
193					}
194
195					$info = $object->_load_ldap_info();
196					$dn = $object->_load_ldap_dn($info);
197
198					$result = $ldap->update($dn, $info, $user, $olddn);
199				}
200
201				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
202			}
203		} elseif ($action == 'USER_ENABLEDISABLE') {
204			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
205		} elseif ($action == 'USER_DELETE') {
206			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
207			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
208				$ldap = new Ldap();
209				$result = $ldap->connect_bind();
210
211				if ($result > 0) {
212					$info = $object->_load_ldap_info();
213					$dn = $object->_load_ldap_dn($info);
214
215					$result = $ldap->delete($dn);
216				}
217
218				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
219			}
220		} elseif ($action == 'USER_SETINGROUP') {
221			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
222			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
223				$ldap = new Ldap();
224				$result = $ldap->connect_bind();
225
226				if ($result > 0) {
227					// Must edit $object->newgroupid
228					$usergroup = new UserGroup($this->db);
229					if ($object->newgroupid > 0) {
230						$usergroup->fetch($object->newgroupid);
231
232						$oldinfo = $usergroup->_load_ldap_info();
233						$olddn = $usergroup->_load_ldap_dn($oldinfo);
234
235						// Verify if entry exist
236						$container = $usergroup->_load_ldap_dn($oldinfo, 1);
237						$search = "(".$usergroup->_load_ldap_dn($oldinfo, 2).")";
238						$records = $ldap->search($container, $search);
239						if (count($records) && $records['count'] == 0) {
240							$olddn = '';
241						}
242
243						$info = $usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call)
244						$dn = $usergroup->_load_ldap_dn($info);
245
246						$result = $ldap->update($dn, $info, $user, $olddn);
247					}
248				}
249
250				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
251			}
252		} elseif ($action == 'USER_REMOVEFROMGROUP') {
253			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
254			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
255				$ldap = new Ldap();
256				$result = $ldap->connect_bind();
257
258				if ($result > 0) {
259					// Must edit $object->newgroupid
260					$usergroup = new UserGroup($this->db);
261					if ($object->oldgroupid > 0) {
262						$usergroup->fetch($object->oldgroupid);
263
264						$oldinfo = $usergroup->_load_ldap_info();
265						$olddn = $usergroup->_load_ldap_dn($oldinfo);
266
267						// Verify if entry exist
268						$container = $usergroup->_load_ldap_dn($oldinfo, 1);
269						$search = "(".$usergroup->_load_ldap_dn($oldinfo, 2).")";
270						$records = $ldap->search($container, $search);
271						if (count($records) && $records['count'] == 0) {
272							$olddn = '';
273						}
274
275						$info = $usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call)
276						$dn = $usergroup->_load_ldap_dn($info);
277
278						$result = $ldap->update($dn, $info, $user, $olddn);
279					}
280				}
281
282				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
283			}
284		}
285
286		// Groupes
287		elseif ($action == 'USERGROUP_CREATE') {
288			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
289			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
290				$ldap = new Ldap();
291				$result = $ldap->connect_bind();
292
293				if ($result > 0) {
294					$info = $object->_load_ldap_info();
295					$dn = $object->_load_ldap_dn($info);
296
297					// Get a gid number for objectclass PosixGroup if none was provided
298					if (empty($info[$conf->global->LDAP_GROUP_FIELD_GROUPID]) && in_array('posixGroup', $info['objectclass'])) {
299						$info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS');
300					}
301
302					$result = $ldap->add($dn, $info, $user);
303				}
304
305				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
306			}
307		} elseif ($action == 'USERGROUP_MODIFY') {
308			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
309			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
310				$ldap = new Ldap();
311				$result = $ldap->connect_bind();
312
313				if ($result > 0) {
314					if (empty($object->oldcopy) || !is_object($object->oldcopy)) {
315						dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING);
316						$object->oldcopy = clone $object;
317					}
318
319					$oldinfo = $object->oldcopy->_load_ldap_info();
320					$olddn = $object->oldcopy->_load_ldap_dn($oldinfo);
321
322					// Verify if entry exist
323					$container = $object->oldcopy->_load_ldap_dn($oldinfo, 1);
324					$search = "(".$object->oldcopy->_load_ldap_dn($oldinfo, 2).")";
325					$records = $ldap->search($container, $search);
326					if (count($records) && $records['count'] == 0) {
327						$olddn = '';
328					}
329
330					$info = $object->_load_ldap_info();
331					$dn = $object->_load_ldap_dn($info);
332
333					$result = $ldap->update($dn, $info, $user, $olddn);
334				}
335
336				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
337			}
338		} elseif ($action == 'USERGROUP_DELETE') {
339			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
340			if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') {
341				$ldap = new Ldap();
342				$result = $ldap->connect_bind();
343
344				if ($result > 0) {
345					$info = $object->_load_ldap_info();
346					$dn = $object->_load_ldap_dn($info);
347
348					$result = $ldap->delete($dn);
349				}
350
351				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
352			}
353		}
354
355		// Contacts
356		elseif ($action == 'CONTACT_CREATE') {
357			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
358			if (!empty($conf->global->LDAP_CONTACT_ACTIVE)) {
359				$ldap = new Ldap();
360				$result = $ldap->connect_bind();
361
362				if ($result > 0) {
363					$info = $object->_load_ldap_info();
364					$dn = $object->_load_ldap_dn($info);
365
366					$result = $ldap->add($dn, $info, $user);
367				}
368
369				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
370			}
371		} elseif ($action == 'CONTACT_MODIFY') {
372			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
373			if (!empty($conf->global->LDAP_CONTACT_ACTIVE)) {
374				$ldap = new Ldap();
375				$result = $ldap->connect_bind();
376
377				if ($result > 0) {
378					if (empty($object->oldcopy) || !is_object($object->oldcopy)) {
379						dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING);
380						$object->oldcopy = clone $object;
381					}
382
383					$oldinfo = $object->oldcopy->_load_ldap_info();
384					$olddn = $object->oldcopy->_load_ldap_dn($oldinfo);
385
386					// Verify if entry exist
387					$container = $object->oldcopy->_load_ldap_dn($oldinfo, 1);
388					$search = "(".$object->oldcopy->_load_ldap_dn($oldinfo, 2).")";
389					$records = $ldap->search($container, $search);
390					if (count($records) && $records['count'] == 0) {
391						$olddn = '';
392					}
393
394					$info = $object->_load_ldap_info();
395					$dn = $object->_load_ldap_dn($info);
396
397					$result = $ldap->update($dn, $info, $user, $olddn);
398				}
399
400				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
401			}
402		} elseif ($action == 'CONTACT_DELETE') {
403			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
404			if (!empty($conf->global->LDAP_CONTACT_ACTIVE)) {
405				$ldap = new Ldap();
406				$result = $ldap->connect_bind();
407
408				if ($result > 0) {
409					$info = $object->_load_ldap_info();
410					$dn = $object->_load_ldap_dn($info);
411
412					$result = $ldap->delete($dn);
413				}
414
415				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
416			}
417		}
418
419		// Members
420		elseif ($action == 'MEMBER_CREATE') {
421			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
422			if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') {
423				$ldap = new Ldap();
424				$result = $ldap->connect_bind();
425
426				if ($result > 0) {
427					$info = $object->_load_ldap_info();
428					$dn = $object->_load_ldap_dn($info);
429
430					$result = $ldap->add($dn, $info, $user);
431
432					// For member type
433					if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') {
434						if ($object->typeid > 0) {
435							require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php";
436							$membertype = new AdherentType($this->db);
437							$membertype->fetch($object->typeid);
438							$membertype->listMembersForMemberType('', 1);
439
440							$oldinfo = $membertype->_load_ldap_info();
441							$olddn = $membertype->_load_ldap_dn($oldinfo);
442
443							// Verify if entry exist
444							$container = $membertype->_load_ldap_dn($oldinfo, 1);
445							$search = "(".$membertype->_load_ldap_dn($oldinfo, 2).")";
446							$records = $ldap->search($container, $search);
447							if (count($records) && $records['count'] == 0) {
448								$olddn = '';
449							}
450
451							$info = $membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call)
452							$dn = $membertype->_load_ldap_dn($info);
453
454							$result = $ldap->update($dn, $info, $user, $olddn);
455						}
456					}
457				}
458
459				if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
460			}
461		} elseif ($action == 'MEMBER_VALIDATE') {
462			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
463			if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') {
464				// If status field is setup to be synchronized
465				if (!empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) {
466					$ldap = new Ldap();
467					$result = $ldap->connect_bind();
468
469					if ($result > 0) {
470						$info = $object->_load_ldap_info();
471						$dn = $object->_load_ldap_dn($info);
472						$olddn = $dn; // We know olddn=dn as we change only status
473
474						$result = $ldap->update($dn, $info, $user, $olddn);
475					}
476
477					if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
478				}
479			}
480		} elseif ($action == 'MEMBER_SUBSCRIPTION') {
481			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
482			if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') {
483				// If subscriptions fields are setup to be synchronized
484				if ($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE
485					|| $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT
486					|| $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE
487					|| $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT
488					|| $conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION) {
489					$ldap = new Ldap();
490					$result = $ldap->connect_bind();
491
492					if ($result > 0) {
493						$info = $object->_load_ldap_info();
494						$dn = $object->_load_ldap_dn($info);
495						$olddn = $dn; // We know olddn=dn as we change only subscriptions
496
497						$result = $ldap->update($dn, $info, $user, $olddn);
498					}
499
500					if ($result < 0) $this->error = "ErrorLDAP ".$ldap->error;
501				}
502			}
503		} elseif ($action == 'MEMBER_MODIFY') {
504			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
505			if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') {
506				$ldap = new Ldap();
507				$result = $ldap->connect_bind();
508
509				if ($result > 0) {
510					if (empty($object->oldcopy) || !is_object($object->oldcopy)) {
511						dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING);
512						$object->oldcopy = clone $object;
513					}
514
515					$oldinfo = $object->oldcopy->_load_ldap_info();
516					$olddn = $object->oldcopy->_load_ldap_dn($oldinfo);
517
518					// Verify if entry exist
519					$container = $object->oldcopy->_load_ldap_dn($oldinfo, 1);
520					$search = "(".$object->oldcopy->_load_ldap_dn($oldinfo, 2).")";
521					$records = $ldap->search($container, $search);
522					if (count($records) && $records['count'] == 0) {
523						$olddn = '';
524					}
525
526					$info = $object->_load_ldap_info();
527					$dn = $object->_load_ldap_dn($info);
528					$newrdn = $object->_load_ldap_dn($info, 2);
529					$newparent = $object->_load_ldap_dn($info, 1);
530
531					$result = $ldap->update($dn, $info, $user, $olddn, $newrdn, $newparent);
532
533					// For member type
534					if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') {
535						require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php";
536
537						/*
538						 * Change member info
539						 */
540						$newmembertype = new AdherentType($this->db);
541						$newmembertype->fetch($object->typeid);
542						$newmembertype->listMembersForMemberType('', 1);
543
544						$oldinfo = $newmembertype->_load_ldap_info();
545						$olddn = $newmembertype->_load_ldap_dn($oldinfo);
546
547						// Verify if entry exist
548						$container = $newmembertype->_load_ldap_dn($oldinfo, 1);
549						$search = "(".$newmembertype->_load_ldap_dn($oldinfo, 2).")";
550						$records = $ldap->search($container, $search);
551						if (count($records) && $records['count'] == 0) {
552							$olddn = '';
553						}
554
555						$info = $newmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call)
556						$dn = $newmembertype->_load_ldap_dn($info);
557
558						$result = $ldap->update($dn, $info, $user, $olddn);
559
560						if ($object->oldcopy->typeid != $object->typeid) {
561							/*
562							 * Remove member in old member type
563							 */
564							$oldmembertype = new AdherentType($this->db);
565							$oldmembertype->fetch($object->oldcopy->typeid);
566							$oldmembertype->listMembersForMemberType('', 1);
567
568							$oldinfo = $oldmembertype->_load_ldap_info();
569							$olddn = $oldmembertype->_load_ldap_dn($oldinfo);
570
571							// Verify if entry exist
572							$container = $oldmembertype->_load_ldap_dn($oldinfo, 1);
573							$search = "(".$oldmembertype->_load_ldap_dn($oldinfo, 2).")";
574							$records = $ldap->search($container, $search);
575							if (count($records) && $records['count'] == 0) {
576								$olddn = '';
577							}
578
579							$info = $oldmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call)
580							$dn = $oldmembertype->_load_ldap_dn($info);
581
582							$result = $ldap->update($dn, $info, $user, $olddn);
583						}
584					}
585				}
586
587				if ($result <= 0) {
588					$this->errors[] = "ErrorLDAP ".$ldap->error;
589				}
590			}
591		} elseif ($action == 'MEMBER_NEW_PASSWORD') {
592			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
593			if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') {
594				// If password field is setup to be synchronized
595				if ($conf->global->LDAP_FIELD_PASSWORD || $conf->global->LDAP_FIELD_PASSWORD_CRYPTED) {
596					$ldap = new Ldap();
597					$result = $ldap->connect_bind();
598
599					if ($result > 0) {
600						$info = $object->_load_ldap_info();
601						$dn = $object->_load_ldap_dn($info);
602						$olddn = $dn; // We know olddn=dn as we change only password
603
604						$result = $ldap->update($dn, $info, $user, $olddn);
605					}
606
607					if ($result <= 0) {
608						$this->errors[] = "ErrorLDAP ".$ldap->error;
609					}
610				}
611			}
612		} elseif ($action == 'MEMBER_RESILIATE') {
613			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
614			if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') {
615				// If status field is setup to be synchronized
616				if (!empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) {
617					$ldap = new Ldap();
618					$result = $ldap->connect_bind();
619
620					if ($result > 0) {
621						$info = $object->_load_ldap_info();
622						$dn = $object->_load_ldap_dn($info);
623						$olddn = $dn; // We know olddn=dn as we change only status
624
625						$result = $ldap->update($dn, $info, $user, $olddn);
626					}
627
628					if ($result <= 0) {
629						$this->errors[] = "ErrorLDAP ".$ldap->error;
630					}
631				}
632			}
633		} elseif ($action == 'MEMBER_DELETE') {
634			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
635			if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') {
636				$ldap = new Ldap();
637				$result = $ldap->connect_bind();
638
639				if ($result > 0) {
640					$info = $object->_load_ldap_info();
641					$dn = $object->_load_ldap_dn($info);
642
643					$result = $ldap->delete($dn);
644
645					// For member type
646					if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') {
647						if ($object->typeid > 0) {
648							require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php";
649
650							/*
651							 * Remove member in member type
652							 */
653							$membertype = new AdherentType($this->db);
654							$membertype->fetch($object->typeid);
655							$membertype->listMembersForMemberType('a.rowid != '.$object->id, 1); // remove deleted member from the list
656
657							$oldinfo = $membertype->_load_ldap_info();
658							$olddn = $membertype->_load_ldap_dn($oldinfo);
659
660							// Verify if entry exist
661							$container = $membertype->_load_ldap_dn($oldinfo, 1);
662							$search = "(".$membertype->_load_ldap_dn($oldinfo, 2).")";
663							$records = $ldap->search($container, $search);
664							if (count($records) && $records['count'] == 0) {
665								$olddn = '';
666							}
667
668							$info = $membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call)
669							$dn = $membertype->_load_ldap_dn($info);
670
671							$result = $ldap->update($dn, $info, $user, $olddn);
672						}
673					}
674				}
675
676				if ($result <= 0) {
677					$this->errors[] = "ErrorLDAP ".$ldap->error;
678				}
679			}
680		}
681
682		// Members types
683		elseif ($action == 'MEMBER_TYPE_CREATE') {
684			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
685			if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') {
686				$ldap = new Ldap();
687				$result = $ldap->connect_bind();
688
689				if ($result > 0) {
690					$info = $object->_load_ldap_info();
691					$dn = $object->_load_ldap_dn($info);
692
693					// Get a gid number for objectclass PosixGroup
694					if (in_array('posixGroup', $info['objectclass'])) {
695						$info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPE');
696					}
697
698					$result = $ldap->add($dn, $info, $user);
699				}
700
701				if ($result <= 0) {
702					$this->errors[] = "ErrorLDAP ".$ldap->error;
703				}
704			}
705		} elseif ($action == 'MEMBER_TYPE_MODIFY') {
706			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
707			if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') {
708				$ldap = new Ldap();
709				$result = $ldap->connect_bind();
710
711				if ($result > 0) {
712					if (empty($object->oldcopy) || !is_object($object->oldcopy)) {
713						dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING);
714						$object->oldcopy = clone $object;
715					}
716
717					$object->oldcopy->listMembersForMemberType('', 1);
718
719					$oldinfo = $object->oldcopy->_load_ldap_info();
720					$olddn = $object->oldcopy->_load_ldap_dn($oldinfo);
721
722					// Verify if entry exist
723					$container = $object->oldcopy->_load_ldap_dn($oldinfo, 1);
724					$search = "(".$object->oldcopy->_load_ldap_dn($oldinfo, 2).")";
725					$records = $ldap->search($container, $search);
726					if (count($records) && $records['count'] == 0) {
727						$olddn = '';
728					}
729
730					$object->listMembersForMemberType('', 1);
731
732					$info = $object->_load_ldap_info();
733					$dn = $object->_load_ldap_dn($info);
734
735					$result = $ldap->update($dn, $info, $user, $olddn);
736				}
737
738				if ($result <= 0) {
739					$this->errors[] = "ErrorLDAP ".$ldap->error;
740				}
741			}
742		} elseif ($action == 'MEMBER_TYPE_DELETE') {
743			dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
744			if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') {
745				$ldap = new Ldap();
746				$result = $ldap->connect_bind();
747
748				if ($result > 0) {
749					$info = $object->_load_ldap_info();
750					$dn = $object->_load_ldap_dn($info);
751
752					$result = $ldap->delete($dn);
753				}
754
755				if ($result <= 0) {
756					$this->errors[] = "ErrorLDAP ".$ldap->error;
757				}
758			}
759		}
760
761		return $result;
762	}
763}
764