mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-29 19:33:54 +01:00
925 lines
35 KiB
PHP
925 lines
35 KiB
PHP
<?php
|
|
/**************************************************************************\
|
|
* eGroupWare - LDAP wrapper class for contacts *
|
|
* http://www.egroupware.org *
|
|
* Written by Cornelius Weiss <egw@von-und-zu-weiss.de> *
|
|
* -------------------------------------------- *
|
|
* 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 2 of the License, or (at your *
|
|
* option) any later version. *
|
|
\**************************************************************************/
|
|
|
|
/* $Id$ */
|
|
|
|
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.contacts.inc.php');
|
|
|
|
define('ADDRESSBOOK_ALL',0);
|
|
define('ADDRESSBOOK_ACCOUNTS',1);
|
|
define('ADDRESSBOOK_PERSONAL',2);
|
|
define('ADDRESSBOOK_GROUP',3);
|
|
|
|
/**
|
|
* Wrapper class for phpgwapi.contacts_ldap
|
|
* This makes it compatible with vars and parameters of so_sql
|
|
* Maybe one day this becomes a generalized ldap storage object :-)
|
|
*
|
|
* @package addressbook
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
*/
|
|
class so_ldap extends contacts {
|
|
|
|
var $data;
|
|
//var $db_data_cols;
|
|
//var $db_key_cols;
|
|
var $groupName = 'Default';
|
|
|
|
/**
|
|
* @var string $accountName holds the accountname of the current user
|
|
*/
|
|
var $accountName;
|
|
|
|
/**
|
|
* @var object $ldapServerInfo holds the information about the current used ldap server
|
|
*/
|
|
var $ldapServerInfo;
|
|
|
|
/**
|
|
* @var int $ldapLimit how many rows to fetch from ldap server
|
|
*/
|
|
var $ldapLimit = 300;
|
|
|
|
/**
|
|
* @var string $personalContactsDN holds the base DN for the personal addressbooks
|
|
*/
|
|
var $personalContactsDN;
|
|
|
|
/**
|
|
* @var string $sharedContactsDN holds the base DN for the shared addressbooks
|
|
*/
|
|
var $sharedContactsDN;
|
|
|
|
/**
|
|
* @var int $total holds the total count of found rows
|
|
*/
|
|
var $total;
|
|
|
|
# jpegPhoto
|
|
var $inetOrgPersonFields = array(
|
|
'n_fn' => 'cn',
|
|
'n_given' => 'givenname',
|
|
'n_family' => 'sn',
|
|
#'n_middle' => 'phpgwmiddlename',
|
|
#'n_prefix' => 'phpgwprefix',
|
|
#'n_suffix' => 'phpgwsuffix',
|
|
'sound' => 'audio',
|
|
#'bday' => 'phpgwbirthday',
|
|
'note' => 'description',
|
|
#'tz' => 'phpgwtz',
|
|
#'geo' => 'phpgwgeo',
|
|
'url' => 'labeleduri',
|
|
#'pubkey' => 'phpgwpublickey',
|
|
|
|
'org_name' => 'o',
|
|
'org_unit' => 'ou',
|
|
'title' => 'title',
|
|
|
|
'adr_one_street' => 'street',
|
|
'adr_one_locality' => 'l',
|
|
'adr_one_region' => 'st',
|
|
'adr_one_postalcode' => 'postalcode',
|
|
#'adr_one_countryname' => 'co',
|
|
#'adr_one_type' => 'phpgwadronetype',
|
|
#'label' => 'phpgwaddresslabel',
|
|
|
|
#'adr_two_street' => 'phpgwadrtwostreet',
|
|
#'adr_two_locality' => 'phpgwadrtwolocality',
|
|
#'adr_two_region' => 'phpgwadrtworegion',
|
|
#'adr_two_postalcode' => 'phpgwadrtwopostalcode',
|
|
#'adr_two_countryname' => 'phpgwadrtwocountryname',
|
|
#'adr_two_type' => 'phpgwadrtwotype',
|
|
|
|
'tel_work' => 'telephonenumber',
|
|
'tel_home' => 'homephone',
|
|
#'tel_voice' => 'phpgwvoicetelephonenumber',
|
|
'tel_fax' => 'facsimiletelephonenumber',
|
|
#'tel_msg' => 'phpgwmsgtelephonenumber',
|
|
#'tel_cell' => 'phpgwcelltelephonenumber',
|
|
#'tel_pager' => 'phpgwpagertelephonenumber',
|
|
#'tel_bbs' => 'phpgwbbstelephonenumber',
|
|
#'tel_modem' => 'phpgwmodemtelephonenumber',
|
|
#'tel_car' => 'phpgwmobiletelephonenumber',
|
|
#'tel_isdn' => 'phpgwisdnphonenumber',
|
|
#'tel_video' => 'phpgwvideophonenumber',
|
|
#'tel_prefer' => 'phpgwpreferphone',
|
|
'email' => 'mail',
|
|
#'email_type' => 'phpgwmailtype',
|
|
#'email_home' => 'phpgwmailhome',
|
|
#'email_home_type' => 'phpgwmailhometype',
|
|
'room' => 'roomnumber',
|
|
);
|
|
|
|
#displayName
|
|
#mozillaCustom1
|
|
#mozillaCustom2
|
|
#mozillaCustom3
|
|
#mozillaCustom4
|
|
#mozillaHomeUrl
|
|
#mozillaNickname
|
|
#mozillaUseHtmlMail
|
|
#nsAIMid
|
|
#postOfficeBox
|
|
var $mozillaAbPersonFields = array(
|
|
#'fn' => 'cn',
|
|
#'n_given' => 'givenname',
|
|
#'n_family' => 'sn',
|
|
#'n_middle' => 'phpgwmiddlename',
|
|
#'n_prefix' => 'phpgwprefix',
|
|
#'n_suffix' => 'phpgwsuffix',
|
|
#'sound' => 'phpgwaudio',
|
|
#'bday' => 'phpgwbirthday',
|
|
#'note' => 'description',
|
|
#'tz' => 'phpgwtz',
|
|
#'geo' => 'phpgwgeo',
|
|
#'url' => 'mozillaworkurl',
|
|
#'pubkey' => 'phpgwpublickey',
|
|
|
|
#'org_name' => 'o',
|
|
#'org_unit' => 'ou',
|
|
#'title' => 'title',
|
|
|
|
#'adr_one_street' => 'street',
|
|
'adr_one_street2' => 'mozillaworkstreet2',
|
|
#'adr_one_locality' => 'l',
|
|
#'adr_one_region' => 'st',
|
|
#'adr_one_postalcode' => 'postalcode',
|
|
#'adr_one_countryname' => 'c',
|
|
#'adr_one_type' => 'phpgwadronetype',
|
|
#'label' => 'phpgwaddresslabel',
|
|
|
|
'adr_two_street' => 'mozillahomestreet',
|
|
'adr_two_street2' => 'mozillahomestreet2',
|
|
'adr_two_locality' => 'mozillahomelocalityname',
|
|
'adr_two_region' => 'mozillahomestate',
|
|
'adr_two_postalcode' => 'mozillahomepostalcode',
|
|
'adr_two_countryname' => 'mozillahomecountryname',
|
|
#'adr_two_type' => 'phpgwadrtwotype',
|
|
|
|
#'tel_work' => 'telephonenumber',
|
|
#'tel_home' => 'homephone',
|
|
#'tel_voice' => 'phpgwvoicetelephonenumber',
|
|
'tel_fax' => 'fax',
|
|
#'tel_msg' => 'phpgwmsgtelephonenumber',
|
|
'tel_cell' => 'mobile',
|
|
'tel_pager' => 'pager',
|
|
#'tel_bbs' => 'phpgwbbstelephonenumber',
|
|
#'tel_modem' => 'phpgwmodemtelephonenumber',
|
|
#'tel_car' => 'phpgwmobiletelephonenumber',
|
|
#'tel_isdn' => 'phpgwisdnphonenumber',
|
|
#'tel_video' => 'phpgwvideophonenumber',
|
|
#'tel_prefer' => 'phpgwpreferphone',
|
|
#'email' => 'mail',
|
|
#'email_type' => 'phpgwmailtype',
|
|
'email_home' => 'mozillasecondemail',
|
|
#'email_home_type' => 'phpgwmailhometype',
|
|
'url_home' => 'mozillahomeurl',
|
|
);
|
|
|
|
# homeFacsimileTelephoneNumber
|
|
# otherPhone
|
|
# businessRole
|
|
# managerName
|
|
# assistantName
|
|
# otherPostalAddress
|
|
# mailer
|
|
# anniversary
|
|
# spouseName
|
|
# companyPhone
|
|
# callbackPhone
|
|
# otherFacsimileTelephoneNumber
|
|
# radio
|
|
# telex
|
|
# tty
|
|
# categories(deprecated)
|
|
# calendarURI
|
|
# freeBusyURI
|
|
var $evolutionPersonFields = array(
|
|
'fn' => 'fileas',
|
|
#'n_given' => 'givenname',
|
|
#'n_family' => 'sn',
|
|
#'n_middle' => 'phpgwmiddlename',
|
|
#'n_prefix' => 'phpgwprefix',
|
|
#'n_suffix' => 'phpgwsuffix',
|
|
#'sound' => 'phpgwaudio',
|
|
'bday' => 'birthdate',
|
|
'note' => 'note',
|
|
#'tz' => 'phpgwtz',
|
|
#'geo' => 'phpgwgeo',
|
|
#'url' => 'mozillaworkurl',
|
|
#'pubkey' => 'phpgwpublickey',
|
|
|
|
#'org_name' => 'o',
|
|
#'org_unit' => 'ou',
|
|
#'title' => 'title',
|
|
|
|
#'adr_one_street' => 'street',
|
|
#'adr_one_locality' => 'l',
|
|
#'adr_one_region' => 'st',
|
|
#'adr_one_postalcode' => 'postalcode',
|
|
#'adr_one_countryname' => 'c',
|
|
#'adr_one_type' => 'phpgwadronetype',
|
|
#'label' => 'phpgwaddresslabel',
|
|
|
|
#'adr_two_street' => 'mozillahomestreet',
|
|
#'adr_two_locality' => 'mozillahomelocalityname',
|
|
#'adr_two_region' => 'mozillahomestate',
|
|
#'adr_two_postalcode' => 'mozillahomepostalcode',
|
|
#'adr_two_countryname' => 'mozillahomecountryname',
|
|
#'adr_two_type' => 'phpgwadrtwotype',
|
|
|
|
#'tel_work' => 'telephonenumber',
|
|
#'tel_home' => 'homephone',
|
|
#'tel_voice' => 'phpgwvoicetelephonenumber',
|
|
#'tel_fax' => 'fax',
|
|
#'tel_msg' => 'phpgwmsgtelephonenumber',
|
|
#'tel_cell' => 'mobile',
|
|
#'tel_pager' => 'pager',
|
|
#'tel_bbs' => 'phpgwbbstelephonenumber',
|
|
#'tel_modem' => 'phpgwmodemtelephonenumber',
|
|
'tel_car' => 'carphone',
|
|
#'tel_isdn' => 'phpgwisdnphonenumber',
|
|
#'tel_video' => 'phpgwvideophonenumber',
|
|
'tel_prefer' => 'primaryphone',
|
|
#'email' => 'mail',
|
|
#'email_type' => 'phpgwmailtype',
|
|
#'email_home' => 'mozillasecondemail',
|
|
#'email_home_type' => 'phpgwmailhometype',
|
|
'cat_id' => 'category',
|
|
'role' => 'businessrole',
|
|
'tel_assistent' => 'assistantphone',
|
|
'assistent' => 'assistantname',
|
|
'n_fileas' => 'fileas',
|
|
);
|
|
|
|
/**
|
|
* constructor of the class
|
|
*
|
|
*/
|
|
function so_ldap()
|
|
{
|
|
//$this->db_data_cols = $this->stock_contact_fields + $this->non_contact_fields;
|
|
$this->accountName = $GLOBALS['egw_info']['user']['account_lid'];
|
|
|
|
$this->personalContactsDN = 'ou=personal,ou=contacts,'. $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
|
$this->sharedContactsDN = 'ou=shared,ou=contacts,'. $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
|
|
|
$this->ldap = CreateObject('phpgwapi.ldap');
|
|
$this->ds = $this->ldap->ldapConnect(
|
|
$GLOBALS['egw_info']['server']['ldap_contact_host'],
|
|
$GLOBALS['egw_info']['user']['account_dn'],
|
|
$GLOBALS['egw_info']['user']['passwd']
|
|
);
|
|
$this->ldapServerInfo = $this->ldap->getLDAPServerInfo($GLOBALS['egw_info']['server']['ldap_contact_host']);
|
|
}
|
|
|
|
/**
|
|
* reads row matched by key and puts all cols in the data array
|
|
*
|
|
* @param array $keys array with keys in form internalName => value, may be a scalar value if only one key
|
|
* @param string/array $extra_cols string or array of strings to be added to the SELECT, eg. "count(*) as num"
|
|
* @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or
|
|
* @return array/boolean data if row could be retrived else False
|
|
*/
|
|
function read($keys,$extra_cols='',$join='')
|
|
{
|
|
$attributes = array_unique(array_merge(array_values($this->inetOrgPersonFields),
|
|
array_values($this->mozillaAbPersonFields),
|
|
array_values($this->evolutionPersonFields)
|
|
));
|
|
|
|
#$rows = $this->searchLDAP($GLOBALS['egw_info']['server']['ldap_contact_context'], "(|(entryUUID=$keys)(uid=$keys))", $attributes, ADDRESSBOOK_ALL);
|
|
|
|
#_debug_array($rows);
|
|
|
|
#return $rows[0];
|
|
|
|
sort($attributes);
|
|
$attributes[] = 'entryUUID';
|
|
$attributes[] = 'objectClass';
|
|
$attributes[] = 'uid';
|
|
if($result = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_contact_context'], "(|(entryUUID=$keys)(uid=$keys))", $attributes)) {
|
|
$entry = ldap_get_entries($this->ds, $result);
|
|
#_debug_array($entry);
|
|
$contacts[0]['id'] = $entry[0]['uid'][0] ? $entry[0]['uid'][0] : $entry[0]['entryuuid'][0];
|
|
for($i=0; $i<$entry[0]['objectclass']['count']; $i++) {
|
|
switch(strtolower($entry[0]['objectclass'][$i])) {
|
|
case 'inetorgperson':
|
|
foreach($this->inetOrgPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(!empty($entry[0][$ldapFieldName][0]) && !isset($contacts[0][$egwFieldName])) {
|
|
$contacts[0][$egwFieldName] = $GLOBALS['egw']->translation->convert(($entry[0][$ldapFieldName][0]),'utf-8');
|
|
}
|
|
}
|
|
|
|
#print $entry[0]['cn'][0]."<br>";
|
|
#print $entry[0]['sn'][0]."<br>";
|
|
if(empty($entry[0]['givenname'][0])) {
|
|
$parts = preg_split('/'.$entry[0]['sn'][0].'/', $entry[0]['cn'][0]);
|
|
$contacts[0]['n_prefix'] = trim($parts[0]);
|
|
$contacts[0]['n_suffix'] = trim($parts[1]);
|
|
} else {
|
|
$parts = preg_split('/'. $entry[0]['givenname'][0] .'.*'. $entry[0]['sn'][0] .'/', $entry[0]['cn'][0]);
|
|
$contacts[0]['n_prefix'] = trim($parts[0]);
|
|
$contacts[0]['n_suffix'] = trim($parts[1]);
|
|
if(preg_match('/'. $entry[0]['givenname'][0] .' (.*) '. $entry[0]['sn'][0] .'/',$entry[0]['cn'][0], $matches)) {
|
|
$contacts[0]['n_middle'] = $matches[1];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'mozillaabpersonalpha':
|
|
foreach($this->mozillaAbPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(!empty($entry[0][$ldapFieldName][0]) && !isset($contacts[0][$egwFieldName])) {
|
|
$contacts[0][$egwFieldName] = $GLOBALS['egw']->translation->convert(($entry[0][$ldapFieldName][0]),'utf-8');
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'evolutionperson':
|
|
foreach($this->evolutionPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(!empty($entry[0][$ldapFieldName][0]) && !isset($contacts[0][$egwFieldName])) {
|
|
switch($egwFieldName) {
|
|
case 'cat_id':
|
|
for($ii=0; $ii<$entry[0][$ldapFieldName]['count']; $ii++) {
|
|
if(!empty($contacts[0][$egwFieldName])) $contacts[0][$egwFieldName] .= ',';
|
|
$contacts[0][$egwFieldName] .= ExecMethod('phpgwapi.categories.name2id',$entry[0][$ldapFieldName][$ii]);
|
|
}
|
|
break;
|
|
|
|
# case 'bday':
|
|
# $bdayParts = explode('-',$entry[0][$ldapFieldName][0]);
|
|
# $contacts[0][$egwFieldName] = $bdayParts[1]. '/' .$bdayParts[2]. '/' .$bdayParts[0];
|
|
# break;
|
|
|
|
default;
|
|
if(!empty($entry[0][$ldapFieldName][0]) && !isset($contacts[0][$egwFieldName])) {
|
|
$contacts[0][$egwFieldName] = $GLOBALS['egw']->translation->convert(($entry[0][$ldapFieldName][0]),'utf-8');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if(!empty($entry[0]['fileas'][0])) {
|
|
$contacts[0]['fn'] = $GLOBALS['egw']->translation->convert(($entry[0]['fileas'][0]),'utf-8');
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
$contacts[0]['tid'] = 'n';
|
|
if(strpos($entry[0]['dn'],$this->personalContactsDN)) {
|
|
$contacts[0]['access'] = 'private';
|
|
$contacts[0]['owner'] = $GLOBALS['egw_info']['user']['account_id'];
|
|
} else {
|
|
$contacts[0]['access'] = 'public';
|
|
$contacts[0]['owner'] = -1000;
|
|
}
|
|
# if(strpos($entry[0]['dn'],$this->personalContactsDN)) {
|
|
# $contacts[0]['access'] = 'private';
|
|
# } else {
|
|
# $contacts[0]['access'] = 'public';
|
|
# }
|
|
}
|
|
# _debug_array($contacts);
|
|
return $contacts[0];
|
|
}
|
|
|
|
/**
|
|
* saves the content of data to the db
|
|
*
|
|
* @param array $keys if given $keys are copied to data before saveing => allows a save as
|
|
* @return int 0 on success and errno != 0 else
|
|
*/
|
|
function save($keys=null)
|
|
{
|
|
$contactUID = '';
|
|
|
|
$isUpdate = false;
|
|
$newObjectClasses = array();
|
|
$ldapContact = array();
|
|
$data =& $this->data;
|
|
|
|
#_debug_array($data);exit;
|
|
// generate addressbook dn
|
|
|
|
if((int)$data['owner'] < 0) {
|
|
// group address book
|
|
if(!$groupName = strtolower($GLOBALS['egw']->accounts->id2name((int)$data['owner']))) {
|
|
return false;
|
|
}
|
|
$baseDN = 'cn='. $groupName .','. $this->sharedContactsDN;
|
|
$cn = $groupName;
|
|
} elseif((int)$data['owner'] > 0) {
|
|
// personal addressbook
|
|
$baseDN = 'cn='. strtolower($this->accountName) .','. $this->personalContactsDN;
|
|
$cn = strtolower($this->accountName);
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
// check if $baseDN exists. If not create new one
|
|
if(!$result = ldap_read($this->ds, $baseDN, 'objectclass=*')) {
|
|
if(ldap_errno($this->ds) == 32) {
|
|
// create a admin connection to add the needed DN
|
|
$adminLDAP = CreateObject('phpgwapi.ldap');
|
|
$adminDS = $adminLDAP->ldapConnect();
|
|
|
|
// emtry does not exist, lets try to create it
|
|
$baseDNData['objectClass'] = 'organizationalRole';
|
|
$baseDNData['cn'] = $cn;
|
|
if(!ldap_add($adminDS, $baseDN, $baseDNData)) {
|
|
$adminLDAP->ldapDisconnect();
|
|
return false;
|
|
}
|
|
$adminLDAP->ldapDisconnect();
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
$attributes = array('dn','cn','objectClass','uid');
|
|
if(!empty($this->data[$this->contacts_id])) {
|
|
$contactUID = $this->data[$this->contacts_id];
|
|
|
|
$result = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_contact_context'], "(|(entryUUID=$contactUID)(uid=$contactUID))", $attributes);
|
|
|
|
$oldContactInfo = ldap_get_entries($this->ds, $result);
|
|
$oldObjectclass = $oldContactInfo[0]['objectclass'];
|
|
$isUpdate = true;
|
|
}
|
|
|
|
if(!$contactUID) {
|
|
$contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
|
}
|
|
|
|
$ldapContact['uid'] = $contactUID;
|
|
|
|
if($this->ldapServerInfo->supportsObjectClass('inetOrgPerson')) {
|
|
if(!$isUpdate) {
|
|
$ldapContact['objectclass'][] = 'inetOrgPerson';
|
|
$ldapContact['objectclass'][] = 'person';
|
|
} else {
|
|
if(!in_array('person', $oldObjectclass)) {
|
|
$newObjectClasses['objectClass'][] = 'person';
|
|
}
|
|
if(!in_array('inetOrgPerson', $oldObjectclass) && !in_array('inetorgperson', $oldObjectclass)) {
|
|
$newObjectClasses['objectClass'][] = 'inetOrgPerson';
|
|
}
|
|
}
|
|
foreach($this->inetOrgPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(!empty($data[$egwFieldName])) {
|
|
switch($ldapFieldName) {
|
|
case 'cn':
|
|
$cneGWFields = array('n_prefix', 'n_given', 'n_middle', 'n_family', 'n_suffix');
|
|
foreach($cneGWFields as $cn_eGWField) {
|
|
if(!empty($data[$cn_eGWField])) {
|
|
$ldapContact[$ldapFieldName] .= $data[$cn_eGWField].' ';
|
|
}
|
|
}
|
|
$ldapContact[$ldapFieldName] = trim($ldapContact[$ldapFieldName]);
|
|
break;
|
|
default:
|
|
$ldapContact[$ldapFieldName] = $GLOBALS['egw']->translation->convert(trim($data[$egwFieldName]),$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
break;
|
|
}
|
|
} elseif($isUpdate) {
|
|
$ldapContact[$ldapFieldName] = array();
|
|
}
|
|
}
|
|
}
|
|
|
|
if($this->ldapServerInfo->supportsObjectClass('mozillaAbPersonAlpha')) {
|
|
if(!$isUpdate) {
|
|
$ldapContact['objectclass'][] = 'mozillaAbPersonAlpha';
|
|
} else {
|
|
if(!in_array('mozillaAbPersonAlpha', $oldObjectclass) && !in_array('mozillaabpersonalpha', $oldObjectclass)) {
|
|
$newObjectClasses['objectClass'][] = 'mozillaAbPersonAlpha';
|
|
}
|
|
}
|
|
foreach($this->mozillaAbPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(empty($ldapContact[$ldapFieldName]) && !empty($data[$egwFieldName])) {
|
|
$ldapContact[$ldapFieldName] = $GLOBALS['egw']->translation->convert(trim($data[$egwFieldName]),$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
} elseif(empty($ldapContact[$ldapFieldName]) && $isUpdate) {
|
|
$ldapContact[$ldapFieldName] = array();
|
|
}
|
|
}
|
|
}
|
|
|
|
if($this->ldapServerInfo->supportsObjectClass('mozillaOrgPerson')) {
|
|
if(!$isUpdate) {
|
|
$ldapContact['objectclass'][] = 'mozillaOrgPerson';
|
|
} else {
|
|
if(!in_array('mozillaOrgPerson', $oldObjectclass) && !in_array('mozillaorgperson', $oldObjectclass)) {
|
|
$newObjectClasses['objectClass'][] = 'mozillaOrgPerson';
|
|
}
|
|
}
|
|
foreach($this->mozillaAbPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(empty($ldapContact[$ldapFieldName]) && !empty($data[$egwFieldName])) {
|
|
$ldapContact[$ldapFieldName] = $GLOBALS['egw']->translation->convert(trim($data[$egwFieldName]),$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
} elseif(empty($ldapContact[$ldapFieldName]) && $isUpdate) {
|
|
$ldapContact[$ldapFieldName] = array();
|
|
}
|
|
}
|
|
}
|
|
|
|
if($this->ldapServerInfo->supportsObjectClass('evolutionPerson')) {
|
|
if(!$isUpdate) {
|
|
$ldapContact['objectclass'][] = 'evolutionPerson';
|
|
} else {
|
|
if(!in_array('evolutionPerson', $oldObjectclass) && !in_array('evolutionperson', $oldObjectclass)) {
|
|
$newObjectClasses['objectClass'][] = 'evolutionPerson';
|
|
}
|
|
}
|
|
foreach($this->evolutionPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(empty($ldapContact[$ldapFieldName]) && !empty($data[$egwFieldName])) {
|
|
switch($egwFieldName) {
|
|
case 'cat_id':
|
|
if(!empty($data[$egwFieldName])) {
|
|
$catIDs = explode(',',$data[$egwFieldName]);
|
|
foreach($catIDs as $value) {
|
|
$ldapContact[$ldapFieldName][] = $GLOBALS['egw']->translation->convert(ExecMethod('phpgwapi.categories.id2name',$value),$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
}
|
|
}
|
|
break;
|
|
|
|
# case 'bday':
|
|
# $dateParts = explode('/',$data[$egwFieldName]);
|
|
# $bday = $dateParts[2] .'-'. $dateParts[0] .'-'. $dateParts[1];
|
|
# $ldapContact[$ldapFieldName] = $bday;
|
|
# break;
|
|
|
|
default:
|
|
$ldapContact[$ldapFieldName] = $GLOBALS['egw']->translation->convert(trim($data[$egwFieldName]),$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
break;
|
|
}
|
|
} elseif(empty($ldapContact[$ldapFieldName]) && $isUpdate) {
|
|
$ldapContact[$ldapFieldName] = array();
|
|
}
|
|
$postalAddress = $data['adr_one_street'] .'$'. $data['adr_one_locality'] .', '. $data['adr_one_region'] .'$'. $data['adr_one_postalcode'] .'$$'. $data['adr_one_countryname'];
|
|
if($postalAddress != '$, $$$') {
|
|
$ldapContact['postalAddress'] = $GLOBALS['egw']->translation->convert($postalAddress,$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
} elseif($isUpdate) {
|
|
$ldapContact['postalAddress'] = array();
|
|
}
|
|
$homePostalAddress = $data['adr_two_street'] .'$'. $data['adr_two_locality'] .', '. $data['adr_two_region'] .'$'. $data['adr_two_postalcode'] .'$$'. $data['adr_two_countryname'];
|
|
if($homePostalAddress != '$, $$$') {
|
|
$ldapContact['homePostalAddress'] = $GLOBALS['egw']->translation->convert($homePostalAddress,$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
} elseif($isUpdate) {
|
|
$ldapContact['homePostalAddress'] = array();
|
|
}
|
|
}
|
|
#if(!empty($ldapContact['givenname']) && !empty($ldapContact['sn'])) {
|
|
# $ldapContact['fileas'] = $ldapContact['sn'] .', '. $ldapContact['givenname'];
|
|
#} else {
|
|
# $ldapContact['fileas'] = $ldapContact['sn'];
|
|
#}
|
|
}
|
|
|
|
if($isUpdate) {
|
|
// update entry
|
|
$dn = $oldContactInfo[0]['dn'];
|
|
$needRecreation = false;
|
|
|
|
// add missing objectclasses
|
|
if(count($newObjectClasses) > 0) {
|
|
$result = @ldap_mod_add($this->ds, $dn, $newObjectClasses);
|
|
if(!$result) {
|
|
#print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';exit;
|
|
if(ldap_errno($this->ds) == 69) {
|
|
// need to modify structural objectclass
|
|
$needRecreation = true;
|
|
} else {
|
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// check if we need to rename the DN or need to recreate the contact
|
|
$newRDN = 'uid='. $contactUID;
|
|
$newDN = $newRDN .','. $baseDN;
|
|
if(strtolower($dn) != strtolower($newDN) || $needRecreation) {
|
|
$result = ldap_read($this->ds, $dn, 'objectclass=*');
|
|
$oldContact = ldap_get_entries($this->ds, $result);
|
|
foreach($oldContact[0] as $key => $value) {
|
|
if(is_array($value)) {
|
|
unset($value['count']);
|
|
$newContact[$key] = $value;
|
|
}
|
|
}
|
|
$newContact['uid'] = $contactUID;
|
|
|
|
if(is_array($newObjectClasses['objectClass']) && count($newObjectClasses['objectClass']) > 0) {
|
|
$newContact['objectclass'] = array_merge($newContact['objectclass'], $newObjectClasses['objectClass']);
|
|
}
|
|
|
|
if(ldap_delete($this->ds, $dn)) {
|
|
if(!ldap_add($this->ds, $newDN, $newContact)) {
|
|
print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';_debug_array($newContact);exit;
|
|
}
|
|
} else {
|
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') delete of old '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
|
return false;
|
|
}
|
|
|
|
$dn = $newDN;
|
|
}
|
|
|
|
#_debug_array($ldapContact);exit;
|
|
$result = ldap_modify($this->ds, $dn, $ldapContact);
|
|
if (!$result) {
|
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
|
#print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';exit;
|
|
#_debug_array($ldapContact);exit;
|
|
return false;
|
|
}
|
|
} else {
|
|
$dn = 'uid='. $ldapContact['uid'] .','. $baseDN;
|
|
|
|
#print "Save $dn<bR>";_debug_array($ldapContact);exit;
|
|
$result = ldap_add($this->ds, $dn, $ldapContact);
|
|
|
|
if (!$result) {
|
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') add of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* deletes row representing keys in internal data or the supplied $keys if != null
|
|
*
|
|
* @param array $keys if given array with col => value pairs to characterise the rows to delete
|
|
* @return int affected rows, should be 1 if ok, 0 if an error
|
|
*/
|
|
function delete($keys=null)
|
|
{
|
|
// single entry
|
|
if($keys[$this->contacts_id]) $keys = array( 0 => $keys);
|
|
|
|
if(!is_array($keys)) {
|
|
$keys = array( 0 => $keys);
|
|
}
|
|
|
|
$ret = 0;
|
|
|
|
$attributes = array('dn');
|
|
|
|
foreach($keys as $entry)
|
|
{
|
|
if($result = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_contact_context'], "(|(entryUUID=$entry)(uid=$entry))", $attributes)) {
|
|
$contactInfo = ldap_get_entries($this->ds, $result);
|
|
if(ldap_delete($this->ds, $contactInfo[0]['dn'])) {
|
|
$ret++;
|
|
}
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* searches db for rows matching searchcriteria
|
|
*
|
|
* '*' and '?' are replaced with sql-wildcards '%' and '_'
|
|
*
|
|
* @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
|
|
* @param boolean/string $only_keys=true True returns only keys, False returns all cols. comma seperated list of keys to return
|
|
* @param string $order_by='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY)
|
|
* @param string/array $extra_cols='' string or array of strings to be added to the SELECT, eg. "count(*) as num"
|
|
* @param string $wildcard='' appended befor and after each criteria
|
|
* @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row
|
|
* @param string $op='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together
|
|
* @param mixed $start=false if != false, return only maxmatch rows begining with start, or array($start,$num)
|
|
* @param array $filter=null if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards
|
|
* @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or
|
|
* "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join!
|
|
* @param boolean $need_full_no_count=false If true an unlimited query is run to determine the total number of rows, default false
|
|
* @return array of matching rows (the row is an array of the cols) or False
|
|
*/
|
|
function &search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='',$need_full_no_count=false)
|
|
{
|
|
#_debug_array($criteria); print "OrderBY: $order_by";_debug_array($extra_cols);_debug_array($filter);
|
|
#$order_by = explode(',',$order_by);
|
|
#$order_by = explode(' ',$order_by);
|
|
#$sort = $order_by[0];
|
|
#$order = $order_by[1];
|
|
#$query = $criteria;
|
|
#$fields = $only_keys ? ($only_keys === true ? $this->contacts_id : $only_keys) : '';
|
|
#$limit = $need_full_no_count ? 0 : $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'];
|
|
#return parent::read($start,$limit,$fields,$query,$filter,$sort,$order);
|
|
|
|
$searchFilter = '';
|
|
$categoryFilter = '';
|
|
|
|
$ownerID = (int)$filter['owner'];
|
|
|
|
if($ownerID < 0) {
|
|
if($groupName = $GLOBALS['egw']->accounts->id2name($ownerID)) {
|
|
$searchDN = 'cn='. strtolower($groupName) .','. $this->sharedContactsDN;
|
|
$addressbookType = ADDRESSBOOK_GROUP;
|
|
} else {
|
|
return false;
|
|
}
|
|
} elseif($ownerID > 0) {
|
|
$searchDN = 'cn='. strtolower($this->accountName) .','. $this->personalContactsDN;
|
|
$addressbookType = ADDRESSBOOK_PERSONAL;
|
|
} else {
|
|
$searchDN = $GLOBALS['egw_info']['server']['ldap_contact_context'];
|
|
$addressbookType = ADDRESSBOOK_ALL;
|
|
}
|
|
|
|
// create the search filter
|
|
switch($addressbookType) {
|
|
case ADDRESSBOOK_ALL:
|
|
$objectFilter = '(|(objectclass=inetorgperson)(objectclass=posixaccount))';
|
|
$attributes = array_unique(array_merge(array_values($this->inetOrgPersonFields),
|
|
array_values($this->mozillaAbPersonFields),
|
|
array_values($this->evolutionPersonFields)
|
|
));
|
|
break;
|
|
case ADDRESSBOOK_ACCOUNTS:
|
|
$objectFilter = '(objectclass=posixaccount)';
|
|
$attributes = array_unique(array_merge(array_values($this->inetOrgPersonFields),
|
|
array_values($this->mozillaAbPersonFields),
|
|
array_values($this->evolutionPersonFields)
|
|
));
|
|
break;
|
|
break;
|
|
default:
|
|
$objectFilter = '(objectclass=inetorgperson)';
|
|
$attributes = array_unique(array_merge(array_values($this->inetOrgPersonFields),
|
|
array_values($this->mozillaAbPersonFields),
|
|
array_values($this->evolutionPersonFields)
|
|
));
|
|
break;
|
|
}
|
|
sort($attributes);
|
|
|
|
if($catID = (int)$filter['cat_id']) {
|
|
$catName = $GLOBALS['egw']->translation->convert(ExecMethod('phpgwapi.categories.id2name',$catID),$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
$categoryFilter = "(category=$catName)";
|
|
}
|
|
|
|
#
|
|
if(is_array($criteria) && count($criteria) > 0) {
|
|
$searchFilter = '';
|
|
foreach($criteria as $egwSearchKey => $searchValue) {
|
|
$ldapSearchKey = '';
|
|
if($ldapSearchKey = $this->inetOrgPersonFields[$egwSearchKey]) {
|
|
#print $ldapSearchKey.$searchValue.'<br>';
|
|
$searchString = $GLOBALS['egw']->translation->convert($searchValue,$GLOBALS['egw']->translation->charset(),'utf-8');
|
|
$searchFilter .= "($ldapSearchKey=$wildcard$searchString$wildcard)";
|
|
}
|
|
}
|
|
if($op == 'AND') {
|
|
$searchFilter = "(&$searchFilter)";
|
|
} else {
|
|
$searchFilter = "(|$searchFilter)";
|
|
}
|
|
}
|
|
$ldapFilter = "(&$objectFilter$categoryFilter$searchFilter)";
|
|
|
|
$rows = $this->searchLDAP($searchDN, $ldapFilter, $attributes, $addressbookType);
|
|
|
|
#_debug_array($rows);
|
|
return $rows;
|
|
}
|
|
|
|
function searchLDAP($_ldapContext, $_filter, $_attributes, $_addressbooktype) {
|
|
$this->total = 0;
|
|
|
|
$_attributes[] = 'entryUUID';
|
|
$_attributes[] = 'uid';
|
|
$_attributes[] = 'objectClass';
|
|
$_attributes[] = 'createTimestamp';
|
|
$_attributes[] = 'modifyTimestamp';
|
|
|
|
if($_addressbooktype == ADDRESSBOOK_ALL) {
|
|
$result = ldap_search($this->ds, $_ldapContext, $_filter, $_attributes, 0, $this->ldapLimit);
|
|
} else {
|
|
$result = ldap_list($this->ds, $_ldapContext, $_filter, $_attributes, 0, $this->ldapLimit);
|
|
}
|
|
|
|
#print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';
|
|
if($result) {
|
|
$entries = ldap_get_entries($this->ds, $result);
|
|
$this->total = $entries['count'];
|
|
for($i=0; $i<$entries['count']; $i++) {
|
|
$contacts[$i]['id'] = $entries[$i]['uid'][0] ? $entries[$i]['uid'][0] : $entries[$i]['entryuuid'][0];
|
|
for($ii=0; $ii<$entries[$i]['objectclass']['count']; $ii++) {
|
|
switch(strtolower($entries[$i]['objectclass'][$ii])) {
|
|
case 'inetorgperson':
|
|
foreach($this->inetOrgPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(!empty($entries[$i][$ldapFieldName][0]) && !isset($contacts[$i][$egwFieldName])) {
|
|
$contacts[$i][$egwFieldName] = $GLOBALS['egw']->translation->convert(($entries[$i][$ldapFieldName][0]),'utf-8');
|
|
}
|
|
}
|
|
|
|
#print $entries[$i]['cn'][0]."<br>";
|
|
#print $entries[$i]['sn'][0]."<br>";
|
|
if(empty($entries[$i]['givenname'][0])) {
|
|
$parts = preg_split('/'.$entries[$i]['sn'][0].'/', $entries[$i]['cn'][0]);
|
|
$contacts[$i]['n_prefix'] = trim($parts[0]);
|
|
$contacts[$i]['n_suffix'] = trim($parts[1]);
|
|
} else {
|
|
$parts = preg_split('/'. $entries[$i]['givenname'][0] .'.*'. $entries[$i]['sn'][0] .'/', $entries[$i]['cn'][0]);
|
|
$contacts[$i]['n_prefix'] = trim($parts[0]);
|
|
$contacts[$i]['n_suffix'] = trim($parts[1]);
|
|
if(preg_match('/'. $entries[$i]['givenname'][0] .' (.*) '. $entries[$i]['sn'][0] .'/',$entries[$i]['cn'][0], $matches)) {
|
|
$contacts[$i]['n_middle'] = $matches[1];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'mozillaabpersonalpha':
|
|
foreach($this->mozillaAbPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(!empty($entries[$i][$ldapFieldName][0]) && !isset($contacts[$i][$egwFieldName])) {
|
|
$contacts[$i][$egwFieldName] = $GLOBALS['egw']->translation->convert(($entries[$i][$ldapFieldName][0]),'utf-8');
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'evolutionperson':
|
|
foreach($this->evolutionPersonFields as $egwFieldName => $ldapFieldName) {
|
|
if(!empty($entries[$i][$ldapFieldName][0]) && !isset($contacts[$i][$egwFieldName])) {
|
|
switch($egwFieldName) {
|
|
case 'cat_id':
|
|
for($iii=0; $iii<$entries[$i][$ldapFieldName]['count']; $iii++) {
|
|
if(!empty($contacts[$i][$egwFieldName])) $contacts[$i][$egwFieldName] .= ',';
|
|
$contacts[$i][$egwFieldName] .= ExecMethod('phpgwapi.categories.name2id',$entries[$i][$ldapFieldName][$iii]);
|
|
}
|
|
break;
|
|
|
|
case 'bday':
|
|
$bdayParts = explode('-',$entries[$i][$ldapFieldName][0]);
|
|
$contacts[$i][$egwFieldName] = $bdayParts[1]. '/' .$bdayParts[2]. '/' .$bdayParts[0];
|
|
break;
|
|
default;
|
|
if(!empty($entries[$i][$ldapFieldName][0]) && !isset($contacts[$i][$egwFieldName])) {
|
|
$contacts[$i][$egwFieldName] = $GLOBALS['egw']->translation->convert(($entries[$i][$ldapFieldName][0]),'utf-8');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if(!empty($entries[$i]['fileas'][0])) {
|
|
$contacts[$i]['fn'] = $GLOBALS['egw']->translation->convert(($entries[$i]['fileas'][0]),'utf-8');
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
// the template id for the addressbook
|
|
$contacts[$i]['tid'] = 'n';
|
|
|
|
if(strpos($entries[$i]['dn'],$this->personalContactsDN)) {
|
|
$contacts[$i]['access'] = 'private';
|
|
$contacts[$i]['owner'] = $GLOBALS['egw_info']['user']['account_id'];
|
|
} else {
|
|
$contacts[$i]['access'] = 'public';
|
|
$contacts[$i]['owner'] = -1000;
|
|
}
|
|
|
|
# modifier
|
|
# creator
|
|
if(!empty($entries[$i]['createtimestamp'][0])) {
|
|
$year = substr($entries[$i]['createtimestamp'][0],0,4);
|
|
$month = substr($entries[$i]['createtimestamp'][0],4,2);
|
|
$day = substr($entries[$i]['createtimestamp'][0],6,2);
|
|
$hour = substr($entries[$i]['createtimestamp'][0],8,2);
|
|
$minute = substr($entries[$i]['createtimestamp'][0],10,2);
|
|
$second = substr($entries[$i]['createtimestamp'][0],12,2);
|
|
$contacts[$i]['created'] = mktime($hour, $minute, $second, $month, $day, $year);
|
|
}
|
|
|
|
if(!empty($entries[$i]['modifytimestamp'][0])) {
|
|
$year = substr($entries[$i]['modifytimestamp'][0],0,4);
|
|
$month = substr($entries[$i]['modifytimestamp'][0],4,2);
|
|
$day = substr($entries[$i]['modifytimestamp'][0],6,2);
|
|
$hour = substr($entries[$i]['modifytimestamp'][0],8,2);
|
|
$minute = substr($entries[$i]['modifytimestamp'][0],10,2);
|
|
$second = substr($entries[$i]['modifytimestamp'][0],12,2);
|
|
$contacts[$i]['modified'] = mktime($hour, $minute, $second, $month, $day, $year);
|
|
}
|
|
}
|
|
|
|
#_debug_array($contacts);
|
|
#exit;
|
|
return $contacts;
|
|
}
|
|
#print 'class.so_ldap.inc.php ('. __LINE__ .') renaming of '. $dn .' to '. $newDN .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';
|
|
#print "bad<br>";
|
|
return array();
|
|
}
|
|
|
|
}
|