From 87b81fb2fda13f2bf507b4a1f8dc521b776626ee Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sat, 16 Sep 2017 17:51:18 +0200 Subject: [PATCH] NEW add members types ldap group management --- htdocs/adherents/class/adherent.class.php | 171 +++++----- .../adherents/class/adherent_type.class.php | 301 +++++++++++------- htdocs/adherents/type.php | 24 +- htdocs/adherents/type_ldap.php | 189 +++++++++++ htdocs/admin/ldap.php | 15 +- htdocs/admin/ldap_groups.php | 5 +- htdocs/admin/ldap_members_types.php | 252 +++++++++++++++ htdocs/core/class/conf.class.php | 1 + htdocs/core/class/ldap.class.php | 7 +- htdocs/core/lib/ldap.lib.php | 8 + htdocs/core/lib/member.lib.php | 10 + ...interface_50_modLdap_Ldapsynchro.class.php | 200 +++++++++++- htdocs/langs/en_US/admin.lang | 12 +- htdocs/langs/en_US/errors.lang | 1 + htdocs/langs/en_US/ldap.lang | 2 + htdocs/user/group/ldap.php | 23 +- 16 files changed, 989 insertions(+), 232 deletions(-) create mode 100644 htdocs/adherents/type_ldap.php create mode 100644 htdocs/admin/ldap_members_types.php diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index a1b61358820..47bf219216c 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -714,109 +714,108 @@ class Adherent extends CommonObject * Fonction qui supprime l'adherent et les donnees associees * * @param int $rowid Id of member to delete - * @param User $user User object + * @param User $user User object * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, 0=nothing to do, >0 if OK */ - function delete($rowid, $user, $notrigger=0) - { - global $conf, $langs; + function delete($rowid, $user, $notrigger=0) + { + global $conf, $langs; - $result = 0; + $result = 0; $error=0; $errorflag=0; // Check parameters if (empty($rowid)) $rowid=$this->id; - $this->db->begin(); + $this->db->begin(); - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('MEMBER_DELETE',$user); - if ($result < 0) $error++; - // End call triggers - } + // Remove category + $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-1; + } - // Remove category - $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-1; + // Remove subscription + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-2; + } + } - } + // Remove linked user + if (! $error) + { + $ret=$this->setUserId(0); + if ($ret < 0) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-3; + } + } - // Remove subscription - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-2; - } - } + // Removed extrafields + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + $errorflag=-4; + dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); + } + } + } - // Remove linked user - if (! $error) - { - $ret=$this->setUserId(0); - if ($ret < 0) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-3; - } - } + // Remove adherent + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-5; + } + } - // Removed extrafields - if (! $error) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $error++; - $errorflag=-4; - dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); - } - } - } + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_DELETE',$user); + if ($result < 0) $error++; + // End call triggers + } - // Remove adherent - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-5; - } - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return $errorflag; - } - } + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return $errorflag; + } + } /** diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 82753d08590..7293fd10e90 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -61,6 +61,8 @@ class AdherentType extends CommonObject public $vote; /** @var bool Email sent during validation */ public $mail_valid; + /** @var array Array of members */ + public $members=array(); /** @@ -250,83 +252,137 @@ class AdherentType extends CommonObject } } - /** - * Fonction qui permet de recuperer le status de l'adherent - * - * @param int $rowid Id of member type to load - * @return int <0 if KO, >0 if OK - */ - function fetch($rowid) - { - $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; - $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; - $sql .= " WHERE d.rowid = ".$rowid; + /** + * Fonction qui permet de recuperer le status de l'adherent + * + * @param int $rowid Id of member type to load + * @param bool $load_members Load members or not + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid, $load_members = true) + { + $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; + $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; + $sql .= " WHERE d.rowid = ".$rowid; - dol_syslog("Adherent_type::fetch", LOG_DEBUG); + dol_syslog("Adherent_type::fetch", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); - $this->id = $obj->rowid; - $this->ref = $obj->rowid; - $this->label = $obj->label; - $this->statut = $obj->statut; - $this->subscription = $obj->subscription; - $this->mail_valid = $obj->mail_valid; - $this->note = $obj->note; - $this->vote = $obj->vote; - } - return 1; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + $this->label = $obj->label; + $this->statut = $obj->statut; + $this->subscription = $obj->subscription; + $this->mail_valid = $obj->mail_valid; + $this->note = $obj->note; + $this->vote = $obj->vote; - /** - * Return list of members' type - * - * @return array List of types of members - */ - function liste_array() - { - global $conf,$langs; + if ($load_members) { + $this->members=$this->listMembersForMemberType(); + } + } - $adherenttypes = array(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } - $sql = "SELECT rowid, libelle as label"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; - $sql.= " WHERE entity IN (".getEntity('adherent').")"; + /** + * Return list of members' type + * + * @return array List of types of members + */ + function liste_array() + { + global $conf,$langs; - $resql=$this->db->query($sql); - if ($resql) - { - $nump = $this->db->num_rows($resql); + $adherenttypes = array(); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object($resql); + $sql = "SELECT rowid, libelle as label"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; + $sql.= " WHERE entity IN (".getEntity('adherent').")"; - $adherenttypes[$obj->rowid] = $langs->trans($obj->label); - $i++; - } - } - } - else - { - print $this->db->error(); - } - return $adherenttypes; - } + $resql=$this->db->query($sql); + if ($resql) + { + $nump = $this->db->num_rows($resql); + + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object($resql); + + $adherenttypes[$obj->rowid] = $langs->trans($obj->label); + $i++; + } + } + } + else + { + print $this->db->error(); + } + return $adherenttypes; + } + + /** + * Return array of Member objects for member type this->id (or all if this->id not defined) + * + * @param string $excludefilter Filter to exclude + * @param int $mode 0=Return array of member instance, 1=Return array of members id only + * @return mixed Array of members or -1 on error + */ + function listMembersForMemberType($excludefilter='', $mode=0) + { + global $conf, $user; + + $ret=array(); + + $sql = "SELECT a.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; + $sql.= " WHERE a.entity IN (".getEntity('member').")"; + $sql.= " AND a.fk_adherent_type = ".$this->id; + if (! empty($excludefilter)) $sql.=' AND ('.$excludefilter.')'; + + dol_syslog(get_class($this)."::listUsersForGroup", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + if (! array_key_exists($obj->rowid, $ret)) + { + if ($mode != 1) + { + $memberstatic=new Adherent($this->db); + $memberstatic->fetch($obj->rowid); + $ret[$obj->rowid]=$memberstatic; + } + else $ret[$obj->rowid]=$obj->rowid; + } + } + + $this->db->free($resql); + + return $ret; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } /** * Return clicable name (with picto eventually) @@ -445,60 +501,63 @@ class AdherentType extends CommonObject ); } - /** - * getMailOnValid - * - * @return string Return mail model - */ - function getMailOnValid() - { - global $conf; + /** + * getMailOnValid + * + * @return string Return mail model + */ + function getMailOnValid() + { + global $conf; - if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) - { - return $this->mail_valid; - } - else - { - return $conf->global->ADHERENT_MAIL_VALID; - } - } + if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) + { + return $this->mail_valid; + } + else + { + return $conf->global->ADHERENT_MAIL_VALID; + } + } - /** - * getMailOnSubscription - * - * @return string Return mail model - */ - function getMailOnSubscription() - { - global $conf; - // mail_subscription not defined so never used - if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined - { - return $this->mail_subscription; - } - else - { - return $conf->global->ADHERENT_MAIL_COTIS; - } - } + /** + * getMailOnSubscription + * + * @return string Return mail model + */ + function getMailOnSubscription() + { + global $conf; + + // mail_subscription not defined so never used + if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined + { + return $this->mail_subscription; + } + else + { + return $conf->global->ADHERENT_MAIL_COTIS; + } + } + + /** + * getMailOnResiliate + * + * @return string Return mail model + */ + function getMailOnResiliate() + { + global $conf; + + // NOTE mail_resiliate not defined so never used + if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined + { + return $this->mail_resiliate; + } + else + { + return $conf->global->ADHERENT_MAIL_RESIL; + } + } - /** - * getMailOnResiliate - * - * @return string Return mail model - */ - function getMailOnResiliate() - { - global $conf; - // NOTE mail_resiliate not defined so never used - if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined - { - return $this->mail_resiliate; - } - else - { - return $conf->global->ADHERENT_MAIL_RESIL; - } - } } diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 3d4fb786295..b59d8b7530d 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -113,7 +113,24 @@ if ($action == 'add' && $user->rights->adherent->configurer) $ret = $extrafields->setOptionalsFromPost($extralabels,$object); if ($ret < 0) $error++; - if ($object->label) + if (empty($object->label)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), null, 'errors'); + } + else { + $sql = "SELECT libelle FROM ".MAIN_DB_PREFIX."adherent_type WHERE libelle='".$db->escape($object->label)."'"; + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + } + if ($num) { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorLabelAlreadyExists",$login), null, 'errors'); + } + } + + if (! $error) { $id=$object->create($user); if ($id > 0) @@ -123,13 +140,12 @@ if ($action == 'add' && $user->rights->adherent->configurer) } else { - $mesg=$object->error; + setEventMessages($object->error, $object->errors, 'errors'); $action = 'create'; } } else { - $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")); $action = 'create'; } } @@ -138,6 +154,8 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->fetch($rowid); + $object->oldcopy = clone $object; + $object->label = trim($label); $object->subscription = (int) trim($subscription); $object->note = trim($comment); diff --git a/htdocs/adherents/type_ldap.php b/htdocs/adherents/type_ldap.php new file mode 100644 index 00000000000..e610f651df5 --- /dev/null +++ b/htdocs/adherents/type_ldap.php @@ -0,0 +1,189 @@ + + * Copyright (C) 2006-2017 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/adherents/type_ldap.php + * \ingroup ldap + * \brief Page fiche LDAP members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("members"); +$langs->load("admin"); +$langs->load("ldap"); + +$id = GETPOST('rowid', 'int'); +$action = GETPOST('action','alpha'); + +// Security check +$result=restrictedArea($user,'adherent',$id,'adherent_type'); + +$object = new AdherentType($db); +$object->fetch($id); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('membertypeldapcard','globalcard')); + +/* + * Actions + */ + + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if ($action == 'dolibarr2ldap') + { + $ldap = new Ldap(); + $result = $ldap->connect_bind(); + + if ($result > 0) + { + $info = $object->_load_ldap_info(); + $dn = $object->_load_ldap_dn($info); + $olddn = $dn; // We can say that old dn = dn as we force synchro + + $result = $ldap->update($dn, $info, $user, $olddn); + } + + if ($result >= 0) { + setEventMessages($langs->trans("MemberTypeSynchronized"), null, 'mesgs'); + } + else { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + } +} + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +$head = member_type_prepare_head($object); + +dol_fiche_head($head, 'ldap', $langs->trans("MemberType"), -1, 'group'); + +$linkback = ''.$langs->trans("BackToList").''; + +dol_banner_tab($object, 'rowid', $linkback); + +print '
'; +print '
'; + +print ''; + +// LDAP DN +print '\n"; + +// LDAP Cle +print '\n"; + +// LDAP Server +print '\n"; +print '\n"; +print '\n"; +print '\n"; +print '\n"; + +print '
LDAP '.$langs->trans("LDAPMemberTypeDn").''.$conf->global->LDAP_MEMBER_TYPE_DN."
LDAP '.$langs->trans("LDAPNamingAttribute").''.$conf->global->LDAP_KEY_MEMBERS_TYPES."
LDAP '.$langs->trans("Type").''.$conf->global->LDAP_SERVER_TYPE."
LDAP '.$langs->trans("Version").''.$conf->global->LDAP_SERVER_PROTOCOLVERSION."
LDAP '.$langs->trans("LDAPPrimaryServer").''.$conf->global->LDAP_SERVER_HOST."
LDAP '.$langs->trans("LDAPSecondaryServer").''.$conf->global->LDAP_SERVER_HOST_SLAVE."
LDAP '.$langs->trans("LDAPServerPort").''.$conf->global->LDAP_SERVER_PORT."
'; + +print '
'; + +dol_fiche_end(); + +/* + * Barre d'actions + */ + +print '
'; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) +{ + print ''.$langs->trans("ForceSynchronize").''; +} + +print "
\n"; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) print "
\n"; + + + +// Affichage attributs LDAP +print load_fiche_titre($langs->trans("LDAPInformationsForThisMemberType")); + +print ''; + +print ''; +print ''; +print ''; +print ''; + +// Lecture LDAP +$ldap=new Ldap(); +$result=$ldap->connect_bind(); +if ($result > 0) +{ + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info,1); + $search = "(".$object->_load_ldap_dn($info,2).")"; + $records = $ldap->getAttribute($dn,$search); + + //print_r($records); + + // Affichage arbre + if ((! is_numeric($records) || $records != 0) && (! isset($records['count']) || $records['count'] > 0)) + { + if (! is_array($records)) + { + print ''; + } + else + { + $result=show_ldap_content($records,0,$records['count'],true); + } + } + else + { + print ''; + } + + $ldap->unbind(); + $ldap->close(); +} +else +{ + setEventMessages($ldap->error, $ldap->errors, 'errors'); +} + +print '
'.$langs->trans("LDAPAttributes").''.$langs->trans("Value").'
'.$langs->trans("ErrorFailedToReadLDAP").'
'.$langs->trans("LDAPRecordNotFound").' (dn='.$dn.' - search='.$search.')
'; + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index d5720835f3c..77fdf6fc579 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -68,6 +68,7 @@ if (empty($reshook)) if (! dolibarr_set_const($db, 'LDAP_SYNCHRO_ACTIVE',GETPOST("activesynchro"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_CONTACT_ACTIVE',GETPOST("activecontact"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_ACTIVE',GETPOST("activemembers"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_ACTIVE',GETPOST("activememberstypes"),'chaine',0,'',$conf->entity)) $error++; if (! $error) { @@ -135,7 +136,6 @@ print ''; // Synchro contact active if (! empty($conf->societe->enabled)) { - print ''.$langs->trans("LDAPDnContactActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -147,7 +147,6 @@ if (! empty($conf->societe->enabled)) // Synchro member active if (! empty($conf->adherent->enabled)) { - print ''.$langs->trans("LDAPDnMemberActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -157,6 +156,18 @@ if (! empty($conf->adherent->enabled)) print ''.$langs->trans("LDAPDnMemberActiveExample").''; } +// Synchro member type active +if (! empty($conf->adherent->enabled)) +{ + print ''.$langs->trans("LDAPDnMemberTypeActive").''; + $arraylist=array(); + $arraylist['0']=$langs->trans("No"); + $arraylist['1']=$langs->trans("DolibarrToLDAP"); + //$arraylist['ldap2dolibarr']=$langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; + print $form->selectarray('activememberstypes',$arraylist,$conf->global->LDAP_MEMBER_TYPE_ACTIVE); + print ''.$langs->trans("LDAPDnMemberTypeActiveExample").''; +} + // Fields from hook $parameters=array(); $reshook=$hookmanager->executeHooks('addAdminLdapOptions',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index fc68d815439..d431a7aaf30 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -220,8 +220,9 @@ if (function_exists("ldap_connect")) $dn=$object->_load_ldap_dn($info); // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } $result1=$ldap->delete($dn); // To be sure to delete existing records $result2=$ldap->add($dn,$info,$user); // Now the test diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php new file mode 100644 index 00000000000..47286dc98da --- /dev/null +++ b/htdocs/admin/ldap_members_types.php @@ -0,0 +1,252 @@ + + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2006-2011 Laurent Destailleur + * Copyright (C) 2011-2013 Juanjo Menent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/ldap_members_types.php + * \ingroup ldap + * \brief Page to setup LDAP synchronization for members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("admin"); +$langs->load("errors"); + +if (!$user->admin) + accessforbidden(); + +$action = GETPOST('action','aZ09'); + + +/* + * Actions + */ + +if ($action == 'setvalue' && $user->admin) +{ + $error=0; + $db->begin(); + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_DN',GETPOST("membertype"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_OBJECT_CLASS',GETPOST("objectclass"),'chaine',0,'',$conf->entity)) $error++; + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_FULLNAME',GETPOST("fieldfullname"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_DESCRIPTION',GETPOST("fielddescription"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS',GETPOST("fieldmembertypemembers"),'chaine',0,'',$conf->entity)) $error++; + + // This one must be after the others + $valkey=''; + $key=GETPOST("key"); + if ($key) $valkey=$conf->global->$key; + if (! dolibarr_set_const($db, 'LDAP_KEY_MEMBERS_TYPES',$valkey,'chaine',0,'',$conf->entity)) $error++; + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + dol_print_error($db); + } +} + + + +/* + * View + */ + +llxHeader('',$langs->trans("LDAPSetup"),'EN:Module_LDAP_En|FR:Module_LDAP|ES:Módulo_LDAP'); +$linkback=''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans("LDAPSetup"),$linkback,'title_setup'); + +$head = ldap_prepare_head(); + +// Test si fonction LDAP actives +if (! function_exists("ldap_connect")) +{ + setEventMessages($langs->trans("LDAPFunctionsNotAvailableOnPHP"), null, 'errors'); +} + +dol_fiche_head($head, 'memberstypes', $langs->trans("LDAPSetup"), -1); + + +print $langs->trans("LDAPDescMembersTypes").'
'; +print '
'; + + +print '
'; +print ''; + +$form=new Form($db); + +print ''; +$var=true; + +print ''; +print ''; +print "\n"; + +// DN pour les types de membres + +print ''; +print ''; +print ''; + +// List of object class used to define attributes in structure + +print ''; +print ''; +print ''; + +print '
'.$langs->trans("LDAPSynchronizeMembersTypes").'
'.$langs->trans("LDAPMemberTypeDn").''; +print ''; +print ''.$langs->trans("LDAPMemberTypepDnExample").' 
'.$langs->trans("LDAPMemberTypeObjectClassList").''; +print ''; +print ''.$langs->trans("LDAPMemberTypeObjectClassListExample").' 
'; +print '
'; +print ''; +$var=true; + +print ''; +print ''; +print ''; +print ''; +print "\n"; + +// Filtre + +// Common name + +print ''; +print '"; +print ''; + +// Description + +print ''; +print '"; +print ''; + +// User group + +print ''; +print '"; +print ''; + +print '
'.$langs->trans("LDAPDolibarrMapping").''.$langs->trans("LDAPLdapMapping").''.$langs->trans("LDAPNamingAttribute").'
'.$langs->trans("LDAPFieldName").''; +print ''; +print ''.$langs->trans("LDAPFieldCommonNameExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)?' checked':'').">
'.$langs->trans("LDAPFieldDescription").''; +print ''; +print ''.$langs->trans("LDAPFieldDescriptionExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBER_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)?' checked':'').">
'.$langs->trans("LDAPFieldGroupMembers").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupMembersExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)?' checked':'').">
'; + +print info_admin($langs->trans("LDAPDescValues")); + +dol_fiche_end(); + +print '
'; + +print '
'; + + +/* + * Test de la connexion + */ +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') +{ + $butlabel=$langs->trans("LDAPTestSynchroMemberType"); + $testlabel='testmembertype'; + $key=$conf->global->LDAP_KEY_MEMBERS_TYPES; + $dn=$conf->global->LDAP_MEMBER_TYPE_DN; + $objectclass=$conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS; + + show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); +} + +if (function_exists("ldap_connect")) +{ + if ($_GET["action"] == 'testmembertype') + { + // Creation objet + $object=new AdherentType($db); + $object->initAsSpecimen(); + + // Test synchro + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPES'); + } + + $result1=$ldap->delete($dn); // To be sure to delete existing records + $result2=$ldap->add($dn,$info,$user); // Now the test + $result3=$ldap->delete($dn); // Clean what we did + + if ($result2 > 0) + { + print img_picto('','info').' '; + print ''.$langs->trans("LDAPSynchroOK").'
'; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + + print "
\n"; + print "LDAP input file used for test:

\n"; + print nl2br($ldap->dump_content($dn,$info)); + print "\n
"; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKO"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + } +} + +llxFooter(); +$db->close(); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index ad224fec97d..8dba7f0e8c5 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -254,6 +254,7 @@ class Conf if (! isset($this->global->LDAP_KEY_GROUPS)) $this->global->LDAP_KEY_GROUPS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_CONTACTS)) $this->global->LDAP_KEY_CONTACTS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_MEMBERS)) $this->global->LDAP_KEY_MEMBERS=$this->global->LDAP_FIELD_FULLNAME; + if (! isset($this->global->LDAP_KEY_MEMBERS_TYPES)) $this->global->LDAP_KEY_MEMBERS_TYPES=$this->global->LDAP_FIELD_FULLNAME; // Load translation object with current language if (empty($this->global->MAIN_LANG_DEFAULT)) $this->global->MAIN_LANG_DEFAULT="en_US"; diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 58eedc0ad9d..790772a9803 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -1411,13 +1411,16 @@ class Ldap /** * Return available value of group GID * + * @param string Key of group * @return int gid number */ - function getNextGroupGid() + function getNextGroupGid($keygroup='LDAP_KEY_GROUPS') { global $conf; - $search='('.$conf->global->LDAP_KEY_GROUPS.'=*)'; + if (empty($keygroup)) $keygroup='LDAP_KEY_GROUPS'; + + $search='('.$conf->global->$keygroup.'=*)'; $result = $this->search($this->groups,$search); if($result) { diff --git a/htdocs/core/lib/ldap.lib.php b/htdocs/core/lib/ldap.lib.php index f684af594e5..3db36723b32 100644 --- a/htdocs/core/lib/ldap.lib.php +++ b/htdocs/core/lib/ldap.lib.php @@ -75,6 +75,14 @@ function ldap_prepare_head() $h++; } + if (! empty($conf->adherent->enabled) && ! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE)) + { + $head[$h][0] = DOL_URL_ROOT."/admin/ldap_members_types.php"; + $head[$h][1] = $langs->trans("LDAPMembersTypesSynchro"); + $head[$h][2] = 'memberstypes'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/lib/member.lib.php b/htdocs/core/lib/member.lib.php index 472c040e450..7e5e5e0c604 100644 --- a/htdocs/core/lib/member.lib.php +++ b/htdocs/core/lib/member.lib.php @@ -124,6 +124,16 @@ function member_type_prepare_head(AdherentType $object) $head[$h][2] = 'card'; $h++; + if (! empty($conf->ldap->enabled) && ! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE)) + { + $langs->load("ldap"); + + $head[$h][0] = DOL_URL_ROOT.'/adherents/type_ldap.php?rowid='.$object->id; + $head[$h][1] = $langs->trans("LDAPCard"); + $head[$h][2] = 'ldap'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index 9c5112dd68a..05a9a5a1b20 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -271,7 +271,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers // Get a gid number for objectclass PosixGroup if (in_array('posixGroup',$info['objectclass'])) { - $info['gidNumber'] = $ldap->getNextGroupGid(); + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); } $result=$ldap->add($dn,$info,$user); @@ -429,6 +429,33 @@ class InterfaceLdapsynchro extends DolibarrTriggers $dn=$object->_load_ldap_dn($info); $result=$ldap->add($dn,$info,$user); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $membertype=new AdherentType($this->db); + if ($object->typeid > 0) + { + $membertype->fetch($object->typeid); + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; @@ -518,6 +545,59 @@ class InterfaceLdapsynchro extends DolibarrTriggers $dn=$object->_load_ldap_dn($info); $result=$ldap->update($dn,$info,$user,$olddn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + if ($object->oldcopy->typeid != $object->typeid) + { + /* + * Add member in new member type + */ + $newmembertype=new AdherentType($this->db); + $newmembertype->fetch($object->typeid); + + $oldinfo=$newmembertype->_load_ldap_info(); + $olddn=$newmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$newmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$newmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$newmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$newmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + + /* + * Remove member in old member type + */ + $oldmembertype=new AdherentType($this->db); + $oldmembertype->fetch($object->oldcopy->typeid); + + $oldinfo=$oldmembertype->_load_ldap_info(); + $olddn=$oldmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$oldmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$oldmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$oldmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$oldmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; @@ -585,13 +665,125 @@ class InterfaceLdapsynchro extends DolibarrTriggers $dn=$object->_load_ldap_dn($info); $result=$ldap->delete($dn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + if ($object->typeid > 0) + { + /* + * Remove member in member type + */ + $membertype=new AdherentType($this->db); + $membertype->fetch($object->typeid); + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } - } + } - return $result; - } + // Members types + elseif ($action == 'MEMBER_TYPE_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPE'); + } + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + return $result; + } } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 0fe1040b389..759e7402515 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1253,6 +1253,7 @@ LDAPUsersSynchro=Users LDAPGroupsSynchro=Groups LDAPContactsSynchro=Contacts LDAPMembersSynchro=Members +LDAPMembersTypesSynchro=Members types LDAPSynchronization=LDAP synchronisation LDAPFunctionsNotAvailableOnPHP=LDAP functions are not available on your PHP LDAPToDolibarr=LDAP -> Dolibarr @@ -1261,7 +1262,8 @@ LDAPNamingAttribute=Key in LDAP LDAPSynchronizeUsers=Organization of users in LDAP LDAPSynchronizeGroups=Organization of groups in LDAP LDAPSynchronizeContacts=Organization of contacts in LDAP -LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembersTypes=Organization of foundation's members types in LDAP LDAPPrimaryServer=Primary server LDAPSecondaryServer=Secondary server LDAPServerPort=Server port @@ -1285,12 +1287,18 @@ LDAPDnContactActive=Contacts' synchronization LDAPDnContactActiveExample=Activated/Unactivated synchronization LDAPDnMemberActive=Members' synchronization LDAPDnMemberActiveExample=Activated/Unactivated synchronization +LDAPDnMemberTypeActive=Members types' synchronization +LDAPDnMemberTypeActiveExample=Activated/Unactivated synchronization LDAPContactDn=Dolibarr contacts' DN LDAPContactDnExample=Complete DN (ex: ou=contacts,dc=example,dc=com) LDAPMemberDn=Dolibarr members DN LDAPMemberDnExample=Complete DN (ex: ou=members,dc=example,dc=com) LDAPMemberObjectClassList=List of objectClass LDAPMemberObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) +LDAPMemberTypeDn=Dolibarr members types DN +LDAPMemberTypepDnExample=Complete DN (ex: ou=memberstypes,dc=example,dc=com) +LDAPMemberTypeObjectClassList=List of objectClass +LDAPMemberTypeObjectClassListExample=List of objectClass defining record attributes (ex: top,groupOfUniqueNames) LDAPUserObjectClassList=List of objectClass LDAPUserObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) LDAPGroupObjectClassList=List of objectClass @@ -1302,6 +1310,7 @@ LDAPTestSynchroContact=Test contacts synchronization LDAPTestSynchroUser=Test user synchronization LDAPTestSynchroGroup=Test group synchronization LDAPTestSynchroMember=Test member synchronization +LDAPTestSynchroMemberType=Test member type synchronization LDAPTestSearch= Test a LDAP search LDAPSynchroOK=Synchronization test successful LDAPSynchroKO=Failed synchronization test @@ -1367,6 +1376,7 @@ LDAPDescContact=This page allows you to define LDAP attributes name in LDAP tree LDAPDescUsers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr users. LDAPDescGroups=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr groups. LDAPDescMembers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members module. +LDAPDescMembersTypes=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members types. LDAPDescValues=Example values are designed for OpenLDAP with following loaded schemas: core.schema, cosine.schema, inetorgperson.schema). If you use thoose values and OpenLDAP, modify your LDAP config file slapd.conf to have all thoose schemas loaded. ForANonAnonymousAccess=For an authenticated access (for a write access for example) PerfDolibarr=Performance setup/optimizing report diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 003eedeac8a..a4777f3ae09 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -104,6 +104,7 @@ ErrorForbidden2=Permission for this login can be defined by your Dolibarr admini ErrorForbidden3=It seems that Dolibarr is not used through an authenticated session. Take a look at Dolibarr setup documentation to know how to manage authentications (htaccess, mod_auth or other...). ErrorNoImagickReadimage=Class Imagick is not found in this PHP. No preview can be available. Administrators can disable this tab from menu Setup - Display. ErrorRecordAlreadyExists=Record already exists +ErrorLabelAlreadyExists=This label already exists ErrorCantReadFile=Failed to read file '%s' ErrorCantReadDir=Failed to read directory '%s' ErrorBadLoginPassword=Bad value for login or password diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang index 42e699de311..d6360f3e540 100644 --- a/htdocs/langs/en_US/ldap.lang +++ b/htdocs/langs/en_US/ldap.lang @@ -6,6 +6,7 @@ LDAPInformationsForThisContact=Information in LDAP database for this contact LDAPInformationsForThisUser=Information in LDAP database for this user LDAPInformationsForThisGroup=Information in LDAP database for this group LDAPInformationsForThisMember=Information in LDAP database for this member +LDAPInformationsForThisMemberType=Information in LDAP database for this member type LDAPAttributes=LDAP attributes LDAPCard=LDAP card LDAPRecordNotFound=Record not found in LDAP database @@ -20,6 +21,7 @@ LDAPFieldSkypeExample=Example : skypeName UserSynchronized=User synchronized GroupSynchronized=Group synchronized MemberSynchronized=Member synchronized +MemberTypeSynchronized=Member type synchronized ContactSynchronized=Contact synchronized ForceSynchronize=Force synchronizing Dolibarr -> LDAP ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility. diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php index b7b1597ea74..ae0d974be9a 100644 --- a/htdocs/user/group/ldap.php +++ b/htdocs/user/group/ldap.php @@ -63,30 +63,31 @@ $object->getrights(); if ($action == 'dolibarr2ldap') { - $db->begin(); - $ldap=new Ldap(); $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if ($result > 0) + { + $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We can say that old dn = dn as we force synchro + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } - $result=$ldap->update($dn,$info,$user,$olddn); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We can say that old dn = dn as we force synchro + + $result=$ldap->update($dn,$info,$user,$olddn); + } if ($result >= 0) { setEventMessages($langs->trans("GroupSynchronized"), null, 'mesgs'); - $db->commit(); } else { setEventMessages($ldap->error, $ldap->errors, 'errors'); - $db->rollback(); } }