mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-07 16:44:07 +01:00
moved contact-data (firstname, lastname and email) from the account-table to the contact table:
- all (sql) accounts have now allways a contact associated with them (account_id is added as new column to the contacts table) - contacts queries are simplefied a lot now, as no more join with the accouns-table, union and case when statesments are necessary - lot of the special handling for accounts in the contacts class is no longer needed - new contact-repository mode "sql-ldap" which additional writes all changes to the ldap repository, to allow to use it read-only from eg. thunderbird and still have the full sql speed and features within eGW (not yet fully working!) ==> requites update of API and addressbook to work (setup!)
This commit is contained in:
parent
61b6d0b993
commit
9f59a77b85
@ -408,7 +408,7 @@ class bocontacts extends socontacts
|
||||
|
||||
if (!$contact['tid']) $contact['tid'] = 'n';
|
||||
}
|
||||
if($contact['id'] && !$this->check_perms(EGW_ACL_EDIT,$contact))
|
||||
if(!$this->check_perms($isUpdate ? EGW_ACL_EDIT : EGW_ACL_ADD,$contact))
|
||||
{
|
||||
$this->error = 'access denied';
|
||||
return false;
|
||||
@ -419,8 +419,11 @@ class bocontacts extends socontacts
|
||||
$contact['modifier'] = $this->user;
|
||||
$contact['modified'] = $this->now_su;
|
||||
// set full name and fileas from the content
|
||||
$contact['n_fn'] = $this->fullname($contact);
|
||||
$contact['n_fileas'] = $this->fileas($contact);
|
||||
if (isset($contact['n_family']) && isset($contact['n_given']))
|
||||
{
|
||||
$contact['n_fn'] = $this->fullname($contact);
|
||||
if (isset($contact['org_name'])) $contact['n_fileas'] = $this->fileas($contact);
|
||||
}
|
||||
|
||||
if(!($this->error = parent::save($contact)))
|
||||
{
|
||||
|
@ -91,12 +91,17 @@ class contacts_admin_prefs
|
||||
'Global Categories' => $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'admin.uicategories.index',
|
||||
'appname' => $appname,
|
||||
'global_cats'=> True)),
|
||||
'Custom fields' => $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'admin.customfields.edit',
|
||||
'appname' => $appname,
|
||||
'global_cats'=> True,
|
||||
)),
|
||||
);
|
||||
// custom fields are not availible in LDAP
|
||||
if ($GLOBALS['egw_info']['server']['contact_repository'] != 'ldap')
|
||||
{
|
||||
$file['Custom fields'] = $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'admin.customfields.edit',
|
||||
'appname' => $appname,
|
||||
));
|
||||
}
|
||||
if ($location == 'admin')
|
||||
{
|
||||
display_section($appname,$file);
|
||||
|
@ -209,7 +209,7 @@ class so_ldap
|
||||
$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'];
|
||||
|
||||
if (is_object($GLOBALS['egw']->ldap))
|
||||
if (!is_object($GLOBALS['egw']->ldap))
|
||||
{
|
||||
$GLOBALS['egw']->ldap =& CreateObject('phpgwapi.ldap');
|
||||
}
|
||||
@ -267,11 +267,6 @@ class so_ldap
|
||||
*/
|
||||
function read($contact_id)
|
||||
{
|
||||
if (substr($contact_id,0,8) == 'account:' &&
|
||||
!($contact_id = $GLOBALS['egw']->accounts->id2name((int) substr($contact_id,8))))
|
||||
{
|
||||
return false; // account does not exist
|
||||
}
|
||||
$contact_id = ldap::quote($contact_id);
|
||||
$rows = $this->_searchLDAP($GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||
"(|(entryUUID=$contact_id)(uid=$contact_id))", $this->all_attributes, ADDRESSBOOK_ALL);
|
||||
@ -287,12 +282,16 @@ class so_ldap
|
||||
*/
|
||||
function save($keys=null)
|
||||
{
|
||||
if(is_array($keys))
|
||||
{
|
||||
$this->data = is_array($this->data) ? array_merge($this->data,$keys) : $keys;
|
||||
}
|
||||
$contactUID = '';
|
||||
|
||||
$data =& $this->data;
|
||||
$isUpdate = false;
|
||||
$newObjectClasses = array();
|
||||
$ldapContact = array();
|
||||
$data =& $this->data;
|
||||
|
||||
// generate addressbook dn
|
||||
if((int)$data['owner'])
|
||||
@ -340,7 +339,7 @@ class so_ldap
|
||||
}
|
||||
if(!$contactUID)
|
||||
{
|
||||
$contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
||||
$this->data[$this->contacts_id] = $contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
||||
}
|
||||
|
||||
$ldapContact['uid'] = $contactUID;
|
||||
@ -348,7 +347,7 @@ class so_ldap
|
||||
// add for all supported objectclasses the objectclass and it's attributes
|
||||
foreach($this->schema2egw as $objectclass => $mapping)
|
||||
{
|
||||
if(!$this->ldapServerInfo->supportsObjectClass($objectclass)) continue;
|
||||
if(!$this->ldapServerInfo->supportsObjectClass($objectclass) || $objectclass == 'posixaccount') continue;
|
||||
|
||||
if(!in_array($objectclass, $oldObjectclasses))
|
||||
{
|
||||
@ -433,21 +432,19 @@ class so_ldap
|
||||
$newContact['objectclass'] = array_merge($newContact['objectclass'], $ldapContact['objectClass']);
|
||||
}
|
||||
|
||||
if(ldap_delete($this->ds, $dn))
|
||||
{
|
||||
if(!@ldap_add($this->ds, $newDN, $newContact))
|
||||
{
|
||||
//echo "<p>recreate: ldap_add($this->ds,'$newDN',".print_r($newContact,true).")</p>\n";
|
||||
//print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';_debug_array($newContact);exit;
|
||||
return $this->_error(__LINE__);
|
||||
}
|
||||
}
|
||||
else
|
||||
if(!ldap_delete($this->ds, $dn))
|
||||
{
|
||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') delete of old '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||
return $this->_error(__LINE__);
|
||||
}
|
||||
|
||||
if(!@ldap_add($this->ds, $newDN, $newContact))
|
||||
{
|
||||
//echo "<p>recreate: ldap_add($this->ds,'$newDN',".print_r($newContact,true).")</p>\n";
|
||||
//print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';_debug_array($newContact);exit;
|
||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') re-create contact as '. $newDN .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||
error_log(print_r($newContact,true));
|
||||
return $this->_error(__LINE__);
|
||||
}
|
||||
$dn = $newDN;
|
||||
}
|
||||
unset($ldapContact['objectClass']);
|
||||
@ -456,6 +453,7 @@ class so_ldap
|
||||
{
|
||||
//echo "<p>ldap_modify($this->ds,'$dn',".print_r($ldapContact,true).")</p>\n";
|
||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||
error_log(print_r($ldapContact,true));
|
||||
return $this->_error(__LINE__);
|
||||
}
|
||||
}
|
||||
@ -467,6 +465,7 @@ class so_ldap
|
||||
{
|
||||
//echo "<p>ldap_add($this->ds,'$dn',".print_r($ldapContact,true).")</p>\n";
|
||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') add of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||
error_log(print_r($ldapContact,true));
|
||||
return $this->_error(__LINE__);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,20 @@
|
||||
|
||||
/**
|
||||
* General storage object of the adressbook
|
||||
*
|
||||
* The contact storage has 3 operation modi (contact_repository):
|
||||
* - sql: contacts are stored in the SQL table egw_addressbook & egw_addressbook_extra (custom fields)
|
||||
* - ldap: contacts are stored in LDAP (accounts have to be stored in LDAP too!!!).
|
||||
* Custom fields are not availible in that case!
|
||||
* - sql-ldap: contacts are read and searched in SQL, but saved to both SQL and LDAP.
|
||||
* Other clients (Thunderbird, ...) can use LDAP readonly. The get maintained via eGroupWare only.
|
||||
*
|
||||
* The accounts can be stored in SQL or LDAP too (account_repository):
|
||||
* If the account-repository is different from the contacts-repository, the filter all (no owner set)
|
||||
* will only search the accounts and NOT the contacts! Only the filter accounts (owner=0) shows accounts.
|
||||
*
|
||||
* If sql-ldap is used as contact-storage (LDAP is managed from eGroupWare) the filter all, searches
|
||||
* the accounts in the SQL contacts-table too. Change in made in LDAP, are not detected in that case!
|
||||
*
|
||||
* @package addressbook
|
||||
* @author Cornelius Weiss <egw-AT-von-und-zu-weiss.de>
|
||||
@ -147,11 +161,20 @@ class socontacts
|
||||
$this->user = $GLOBALS['egw_info']['user']['account_id'];
|
||||
$this->memberships = $GLOBALS['egw']->accounts->memberships($this->user,true);
|
||||
|
||||
// contacts backend
|
||||
if($GLOBALS['egw_info']['server']['contact_repository'] == 'ldap')
|
||||
// account backend used
|
||||
if ($GLOBALS['egw_info']['server']['account_repository'])
|
||||
{
|
||||
$this->account_repository = $GLOBALS['egw_info']['server']['account_repository'];
|
||||
}
|
||||
elseif ($GLOBALS['egw_info']['server']['auth_type'])
|
||||
{
|
||||
$this->account_repository = $GLOBALS['egw_info']['server']['auth_type'];
|
||||
}
|
||||
// contacts backend (contacts in LDAP require accounts in LDAP!)
|
||||
if($GLOBALS['egw_info']['server']['contact_repository'] == 'ldap' && $this->account_repository == 'ldap')
|
||||
{
|
||||
$this->contact_repository = 'ldap';
|
||||
$this->somain =& CreateObject('addressbook.so_'.$this->contact_repository);
|
||||
$this->somain =& CreateObject('addressbook.so_ldap');
|
||||
|
||||
// static grants from ldap: all rights for the own personal addressbook and the group ones of the meberships
|
||||
$this->grants = array($this->user => ~0);
|
||||
@ -163,27 +186,23 @@ class socontacts
|
||||
// minimum: $this->columns_to_search = array('n_family','n_given','org_name');
|
||||
$this->columns_to_search = array('n_family','n_middle','n_given','org_name','org_unit','adr_one_location','adr_two_location','note');
|
||||
}
|
||||
else
|
||||
else // sql or sql->ldap
|
||||
{
|
||||
$this->somain =& CreateObject('addressbook.socontacts_sql','addressbook','egw_addressbook',null,'contact_');
|
||||
if ($GLOBALS['egw_info']['server']['contact_repository'] == 'sql-ldap')
|
||||
{
|
||||
$this->contact_repository = 'sql-ldap';
|
||||
}
|
||||
$this->somain =& CreateObject('addressbook.socontacts_sql');
|
||||
// group grants are now grants for the group addressbook and NOT grants for all its members, therefor the param false!
|
||||
$this->grants = $GLOBALS['egw']->acl->get_grants($contact_app,false);
|
||||
|
||||
// remove some columns, absolutly not necessary to search in sql
|
||||
$this->columns_to_search = array_diff(array_values($this->somain->db_cols),array('jpegphoto','owner','tid',
|
||||
'private','id','cat_id','modified','modifier','creator','created','tz'));
|
||||
$this->columns_to_search[] = $this->extra_value; // custome fields from extra_table
|
||||
$this->columns_to_search = array_diff(array_values($this->somain->db_cols),array(
|
||||
'jpegphoto','owner','tid','private','id','cat_id',
|
||||
'modified','modifier','creator','created','tz','account_id',
|
||||
));
|
||||
}
|
||||
// account backend
|
||||
if ($GLOBALS['egw_info']['server']['account_repository'])
|
||||
{
|
||||
$this->account_repository = $GLOBALS['egw_info']['server']['account_repository'];
|
||||
}
|
||||
elseif ($GLOBALS['egw_info']['server']['auth_type'])
|
||||
{
|
||||
$this->account_repository = $GLOBALS['egw_info']['server']['auth_type'];
|
||||
}
|
||||
if ($this->account_repository == 'ldap')
|
||||
if ($this->account_repository == 'ldap' && $this->contact_repository == 'sql')
|
||||
{
|
||||
if ($this->account_repository != $this->contact_repository)
|
||||
{
|
||||
@ -196,18 +215,6 @@ class socontacts
|
||||
$this->account_extra_search = array('uid');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->account_repository != $this->contact_repository)
|
||||
{
|
||||
// contacts in ldap & accounts in sql is not tested or supported at the moment!!!
|
||||
$this->so_accounts =& CreateObject('addressbook.socontacts_sql','addressbook','egw_addressbook',null,'contact_');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->account_extra_search = array('account_firstname','account_lastname','account_email','account_lid');
|
||||
}
|
||||
}
|
||||
// add grants for accounts: admin --> everything, everyone --> read
|
||||
$this->grants[0] = EGW_ACL_READ; // everyone read access
|
||||
if (isset($GLOBALS['egw_info']['user']['apps']['admin'])) // admin rights can be limited by ACL!
|
||||
@ -221,7 +228,7 @@ class socontacts
|
||||
|
||||
$this->somain->contacts_id = 'id';
|
||||
$this->soextra =& CreateObject('etemplate.so_sql');
|
||||
$this->soextra->so_sql('addressbook',$this->extra_table);
|
||||
$this->soextra->so_sql('phpgwapi',$this->extra_table);
|
||||
|
||||
$custom =& CreateObject('admin.customfields',$contact_app);
|
||||
$this->customfields = $custom->get_customfields();
|
||||
@ -246,6 +253,12 @@ class socontacts
|
||||
*/
|
||||
function read_customfields($ids)
|
||||
{
|
||||
foreach($ids as $key => $id)
|
||||
{
|
||||
if (!(int)$id) unset($ids[$key]);
|
||||
}
|
||||
if (!$ids) return array(); // nothing to do, eg. all these contacts are in ldap
|
||||
|
||||
$fields = array();
|
||||
foreach((array)$this->soextra->search(array($this->extra_id => $ids),false) as $data)
|
||||
{
|
||||
@ -283,7 +296,7 @@ class socontacts
|
||||
/**
|
||||
* deletes contact entry including custom fields
|
||||
*
|
||||
* @param mixed $contact array with key id or just the id
|
||||
* @param mixed $contact array with id or just the id
|
||||
* @return boolean true on success or false on failiure
|
||||
*/
|
||||
function delete($contact)
|
||||
@ -295,7 +308,17 @@ class socontacts
|
||||
{
|
||||
// delete customfields, can return 0 if there are no customfields
|
||||
$this->soextra->delete(array($this->extra_id => $contact));
|
||||
|
||||
|
||||
if ($this->contact_repository == 'sql-ldap')
|
||||
{
|
||||
if ($contact['account_id'])
|
||||
{
|
||||
// LDAP uses the uid attributes for the contact-id (dn),
|
||||
// which need to be the account_lid for accounts!
|
||||
$contact['id'] = $GLOBALS['egw']->account->id2name($contact['account_id']);
|
||||
}
|
||||
ExecMethod('addressbook.so_ldap.delete',$contact);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -321,8 +344,22 @@ class socontacts
|
||||
else
|
||||
{
|
||||
$this->somain->data = $this->data2db($contact);
|
||||
$error_nr = $this->somain->save();
|
||||
$contact['id'] = $this->somain->data['id'];
|
||||
if (!($error_nr = $this->somain->save()))
|
||||
{
|
||||
$contact['id'] = $this->somain->data['id'];
|
||||
|
||||
if ($this->contact_repository == 'sql-ldap')
|
||||
{
|
||||
$data = $this->somain->data;
|
||||
if ($contact['account_id'])
|
||||
{
|
||||
// LDAP uses the uid attributes for the contact-id (dn),
|
||||
// which need to be the account_lid for accounts!
|
||||
$data['id'] = $GLOBALS['egw']->account->id2name($contact['account_id']);
|
||||
}
|
||||
ExecMethod('addressbook.so_ldap.save',$data);
|
||||
}
|
||||
}
|
||||
}
|
||||
if($error_nr) return $error_nr;
|
||||
|
||||
@ -358,6 +395,11 @@ class socontacts
|
||||
*/
|
||||
function read($contact_id)
|
||||
{
|
||||
if (substr($contact_id,0,8) == 'account:' &&
|
||||
(!($contact_id = $GLOBALS['egw']->accounts->id2name((int) substr($contact_id,8),'person_id'))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// read main data
|
||||
$backend =& $this->get_backend($contact_id);
|
||||
if (!($contact = $backend->read($contact_id)))
|
||||
@ -369,10 +411,13 @@ class socontacts
|
||||
$this->extra_id => $contact['id'],
|
||||
$this->extra_owner => $contact['owner'],
|
||||
);
|
||||
$customfields = $this->soextra->search($keys,false);
|
||||
foreach ((array)$customfields as $field)
|
||||
if ($this->customfields) // try reading customfields only if we have some
|
||||
{
|
||||
$contact['#'.$field[$this->extra_key]] = $field[$this->extra_value];
|
||||
$customfields = $this->soextra->search($keys,false);
|
||||
foreach ((array)$customfields as $field)
|
||||
{
|
||||
$contact['#'.$field[$this->extra_key]] = $field[$this->extra_value];
|
||||
}
|
||||
}
|
||||
return $this->db2data($contact);
|
||||
}
|
||||
@ -588,9 +633,10 @@ class socontacts
|
||||
* @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 (only used by sql backend!), eg. " RIGHT JOIN egw_accounts USING(account_id)"
|
||||
* @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)
|
||||
function &search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='')
|
||||
{
|
||||
//echo "<p>socontacts::search(".print_r($criteria,true).",'$only_keys','$order_by','$extra_cols','$wildcard','$empty','$op','$start',".print_r($filter,true).",'$join')</p>\n";
|
||||
|
||||
@ -606,15 +652,16 @@ class socontacts
|
||||
if ($backend === $this->somain)
|
||||
{
|
||||
$cols = $this->columns_to_search;
|
||||
if (!$filter['owner']) // extra columns for search if accounts are included, eg. account_lid
|
||||
{
|
||||
$cols = array_merge($cols,$this->account_extra_search);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$cols = $this->account_cols_to_search;
|
||||
}
|
||||
// search the customfields only if some exist, but only for sql!
|
||||
if (get_class($backend) == 'socontacts_sql' && $this->customfields)
|
||||
{
|
||||
$cols[] = $this->extra_value;
|
||||
}
|
||||
foreach($cols as $col)
|
||||
{
|
||||
$criteria[$col] = $search;
|
||||
@ -779,7 +826,7 @@ class socontacts
|
||||
*/
|
||||
function get_fields($type='all',$contact_id=null,$owner=null)
|
||||
{
|
||||
$def = $this->soextra->db->get_table_definitions('addressbook','egw_addressbook');
|
||||
$def = $this->soextra->db->get_table_definitions('phpgwapi','egw_addressbook');
|
||||
|
||||
$all_fields = array();
|
||||
foreach($def['fd'] as $field => $data)
|
||||
|
@ -23,14 +23,13 @@ include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
|
||||
|
||||
class socontacts_sql extends so_sql
|
||||
{
|
||||
var $accounts_table = 'egw_accounts';
|
||||
var $accounts_join = ' JOIN egw_accounts ON person_id=egw_addressbook.contact_id';
|
||||
var $extra_join = ' LEFT JOIN egw_addressbook_extra ON egw_addressbook.contact_id=egw_addressbook_extra.contact_id';
|
||||
var $account_repository = 'sql';
|
||||
var $contact_repository = 'sql';
|
||||
|
||||
function socontacts_sql($app='',$table='',$db=null,$column_prefix='')
|
||||
function socontacts_sql()
|
||||
{
|
||||
$this->so_sql($app,$table,$db,$column_prefix); // calling the constructor of the extended class
|
||||
$this->so_sql('phpgwapi','egw_addressbook',null,'contact_'); // calling the constructor of the extended class
|
||||
|
||||
if ($GLOBALS['egw_info']['server']['account_repository'])
|
||||
{
|
||||
@ -40,6 +39,10 @@ class socontacts_sql extends so_sql
|
||||
{
|
||||
$this->account_repository = $GLOBALS['egw_info']['server']['auth_type'];
|
||||
}
|
||||
if ($GLOBALS['egw_info']['server']['contact_repository'])
|
||||
{
|
||||
$this->contact_repository = $GLOBALS['egw_info']['server']['contact_repository'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,6 +87,10 @@ class socontacts_sql extends so_sql
|
||||
}
|
||||
else // search all addressbooks, incl. accounts
|
||||
{
|
||||
if ($this->account_repository != 'sql' && $this->contact_repository != 'sql-ldap')
|
||||
{
|
||||
$filter[] = 'contact_owner != 0'; // in case there have been accounts in sql previously
|
||||
}
|
||||
$filter[] = "(contact_owner=".(int)$GLOBALS['egw_info']['user']['account_id'].
|
||||
" OR contact_private=0 AND contact_owner IN (".
|
||||
implode(',',array_keys($this->grants))."))";
|
||||
@ -223,52 +230,15 @@ class socontacts_sql extends so_sql
|
||||
}
|
||||
else // search all addressbooks, incl. accounts
|
||||
{
|
||||
if ($this->account_repository != 'sql' && $this->contact_repository != 'sql-ldap')
|
||||
{
|
||||
$filter[] = 'contact_owner != 0'; // in case there have been accounts in sql previously
|
||||
}
|
||||
$filter[] = "($this->table_name.contact_owner=".(int)$GLOBALS['egw_info']['user']['account_id'].
|
||||
" OR contact_private=0 AND $this->table_name.contact_owner IN (".
|
||||
implode(',',array_keys($this->grants)).") OR $this->table_name.contact_owner IS NULL)";
|
||||
}
|
||||
}
|
||||
if (!$owner && $this->account_repository == 'sql') // owner not set (=all) or 0 --> include accounts
|
||||
{
|
||||
if (!is_array($extra_cols)) $extra_cols = $extra_cols ? explode(',',$extra_cols) : array();
|
||||
$accounts2contacts = array(
|
||||
'contact_id' => "CASE WHEN $this->table_name.contact_id IS NULL THEN ".$this->db->concat("'account:'",'account_id').
|
||||
" ELSE $this->table_name.contact_id END AS contact_id",
|
||||
'contact_owner' => "CASE WHEN $this->table_name.contact_owner IS NULL THEN 0 ELSE $this->table_name.contact_owner END AS contact_owner",
|
||||
'contact_tid' => 'CASE WHEN contact_tid IS NULL THEN \'n\' ELSE contact_tid END AS contact_tid',
|
||||
'n_family' => 'CASE WHEN n_family IS NULL THEN account_lastname ELSE n_family END AS n_family',
|
||||
'n_given' => 'CASE WHEN n_given IS NULL THEN account_firstname ELSE n_given END AS n_given',
|
||||
'n_fn' => 'CASE WHEN n_fn IS NULL THEN '.$this->db->concat('account_firstname',"' '",'account_lastname').' ELSE n_fn END AS n_fn',
|
||||
'contact_email' => 'CASE WHEN contact_email IS NULL THEN account_email ELSE contact_email END AS contact_email',
|
||||
);
|
||||
$extra_cols = $extra_cols ? array_merge(is_array($extra_cols) ? $extra_cols : implode(',',$extra_cols),array_values($accounts2contacts)) :
|
||||
array_values($accounts2contacts);
|
||||
|
||||
// we need to remove the above columns from the select list, as they are added again via extra_cols and
|
||||
// having them double is ambigues
|
||||
if (!$only_keys)
|
||||
{
|
||||
$only_keys = array_diff(array_keys($this->db_cols),array_keys($accounts2contacts));
|
||||
}
|
||||
elseif($only_keys !== true)
|
||||
{
|
||||
if (!is_array($only_keys)) $only_keys = explode(',',$only_keys);
|
||||
|
||||
foreach(array_keys($accounts2contacts) as $col)
|
||||
{
|
||||
if (($key = array_search($col,$only_keys)) !== false ||
|
||||
($key = array_search(str_replace('contact_','',$col),$only_keys)) !== false)
|
||||
{
|
||||
unset($only_keys[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->_fix_filter($filter,$accounts2contacts);
|
||||
// dont list groups
|
||||
$filter[] = "(account_type != 'g' OR account_type IS NULL)";
|
||||
|
||||
if (is_array($criteria)) $this->_fix_filter($criteria,$accounts2contacts,$wildcard);
|
||||
}
|
||||
if ($criteria['contact_value']) // search the custom-fields
|
||||
{
|
||||
$join .= $this->extra_join;
|
||||
@ -285,70 +255,9 @@ class socontacts_sql extends so_sql
|
||||
unset($filter['owner']);
|
||||
}
|
||||
}
|
||||
if ($this->account_repository == 'sql')
|
||||
{
|
||||
if (is_null($owner)) // search for accounts AND contacts of all addressbooks
|
||||
{
|
||||
/* only enable that after testing with postgres, I dont want to break more postgres stuff ;-)
|
||||
if ($this->db->capabilities['outer_join'])
|
||||
{
|
||||
$join = 'OUTER'.$this->accounts_join.' '.$join;
|
||||
}
|
||||
else */ // simulate the outer join with a union
|
||||
{
|
||||
parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,'UNION',$filter,
|
||||
'LEFT'.$this->accounts_join.$join,$need_full_no_count);
|
||||
$filter[] = '(person_id=0 OR person_id IS NULL)'; // unfortunally both is used in eGW
|
||||
parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,'UNION',$filter,
|
||||
'RIGHT'.$this->accounts_join.$join,$need_full_no_count);
|
||||
}
|
||||
}
|
||||
elseif (!$owner) // search for accounts only
|
||||
{
|
||||
$join = ' RIGHT'.$this->accounts_join.$join;
|
||||
$filter[] = "account_type='u'"; // no groups
|
||||
}
|
||||
}
|
||||
return parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixing column-names in the filter to use CASE expressions to include the account-data
|
||||
*
|
||||
* @param array &$filter column => value pairs or sql strings
|
||||
* @param array $accounts2contacts mapping column-name => sql statement
|
||||
* @param string $wildcard='' wildcard if one should be append before and after the value
|
||||
*/
|
||||
function _fix_filter(&$filter,$accounts2contacts,$wildcard='')
|
||||
{
|
||||
foreach($filter as $col => $value)
|
||||
{
|
||||
if (!is_int($col) && ($db_col = array_search($col,$this->db_cols)) !== false)
|
||||
{
|
||||
if (isset($accounts2contacts[$db_col]))
|
||||
{
|
||||
unset($filter[$col]);
|
||||
$filter[] = str_replace(' AS '.$db_col,'',$accounts2contacts[$db_col]).
|
||||
($value === "!''" ? "!=''" : ($wildcard ? ' LIKE ' : '=').
|
||||
$this->db->quote($wildcard.$value.$wildcard,$this->table_def['fd'][$db_col]['type']));
|
||||
}
|
||||
elseif($value === "!''") // not empty query, will match all accounts, as their value is NULL not ''
|
||||
{
|
||||
unset($filter[$col]);
|
||||
$filter[] = "($db_col != '' AND $db_col IS NOT NULL)";
|
||||
}
|
||||
}
|
||||
elseif (preg_match("/^([a-z0-9_]+) *(=|!=|LIKE|NOT LIKE|=!) *'(.*)'\$/i",$value,$matches))
|
||||
{
|
||||
if (($db_col = array_search($matches[1],$this->db_cols)) !== false && isset($accounts2contacts[$db_col]))
|
||||
{
|
||||
if ($matches[2] == '=!') $matches[2] = '!=';
|
||||
$filter[$col] = str_replace(' AS '.$db_col,'',$accounts2contacts[$db_col]).' '.$matches[2].' \''.$matches[3].'\'';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fix cat_id filter to search in comma-separated multiple cats and return subcats
|
||||
*
|
||||
@ -368,131 +277,4 @@ class socontacts_sql extends so_sql
|
||||
}
|
||||
return '('.implode(' OR ',$cat_filter).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* reads contact data including custom fields
|
||||
*
|
||||
* reimplemented to read/convert accounts and return the account_id for them
|
||||
*
|
||||
* @param integer/string $contact_id contact_id or 'account:'.account_id
|
||||
* @return array/boolean data if row could be retrived else False
|
||||
*/
|
||||
function read($contact_id)
|
||||
{
|
||||
//echo "<p>socontacts_sql::read($contact_id)</p>\n";
|
||||
if (substr($contact_id,0,8) == 'account:')
|
||||
{
|
||||
$account_id = (int) substr($contact_id,8);
|
||||
|
||||
if (!$GLOBALS['egw']->accounts->exists($account_id)) return false; // account does not exist
|
||||
|
||||
// check if the account is already linked with a contact, if not create one with the content of the account
|
||||
if (!($contact_id = $GLOBALS['egw']->accounts->id2name($account_id,'person_id')) &&
|
||||
!($matching_contact_id = $this->_find_unique_contact(
|
||||
$GLOBALS['egw']->accounts->id2name($account_id,'account_firstname'),
|
||||
$GLOBALS['egw']->accounts->id2name($account_id,'account_lastname'))))
|
||||
{
|
||||
// as the account object has no function to just read a record and NOT override it's internal data,
|
||||
// we have to instanciate a new object and can NOT use $GLOBALS['egw']->accounts !!!
|
||||
$account =& new accounts($account_id,'u');
|
||||
$account->read();
|
||||
|
||||
if (!$account->data['account_id']) return false; // account not found
|
||||
|
||||
$this->init();
|
||||
$this->save(array(
|
||||
'n_family' => $account->data['lastname'],
|
||||
'n_given' => $account->data['firstname'],
|
||||
'n_fn' => $account->data['firstname'].' '.$account->data['lastname'],
|
||||
'n_fileas' => $account->data['lastname'].', '.$account->data['firstname'],
|
||||
'email' => $account->data['email'],
|
||||
'owner' => 0,
|
||||
'tid' => 'n',
|
||||
'creator' => $GLOBALS['egw_info']['user']['account_id'],
|
||||
'created' => time(),
|
||||
'modifier' => $GLOBALS['egw_info']['user']['account_id'],
|
||||
'modified' => time(),
|
||||
),$account_id);
|
||||
|
||||
return $this->data+array('account_id' => $account_id);
|
||||
}
|
||||
elseif ($matching_contact_id)
|
||||
{
|
||||
//echo "<p>socontacts_sql($contact_id) account_id=$account_id, matching_contact_id=$matching_contact_id</p>\n";
|
||||
$contact = parent::read($matching_contact_id);
|
||||
$contact['owner'] = 0;
|
||||
$this->save($contact,$account_id);
|
||||
|
||||
return $this->data+array('account_id' => $account_id);
|
||||
}
|
||||
//echo "<p>socontacts_sql::read() account_id='$account_id', contact_id='$contact_id'</p>\n"; exit;
|
||||
}
|
||||
if (($contact = parent::read($contact_id)) && !$contact['owner']) // return account_id for accounts
|
||||
{
|
||||
$contact['account_id'] = $GLOBALS['egw']->accounts->name2id($contact_id,'person_id');
|
||||
}
|
||||
return $contact;
|
||||
}
|
||||
|
||||
function _find_unique_contact($firstname,$lastname)
|
||||
{
|
||||
$contacts =& $this->search(array(
|
||||
'contact_owner != 0',
|
||||
'n_given' => $firstname,
|
||||
'n_family' => $lastname,
|
||||
'private' => 0,
|
||||
));
|
||||
|
||||
return $contacts && count($contacts) == 1 ? $contacts[0]['id'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the content of data to the db
|
||||
*
|
||||
* reimplemented to write for accounts some of the data to the account too and link it with the contact
|
||||
*
|
||||
* @param array $keys if given $keys are copied to data before saveing => allows a save as
|
||||
* @param int $account_id if called by read account_id of account to save/link with contact (we dont overwrite the account-data in that case),
|
||||
* otherwise we try getting it by accounts::name2id('person_id',$contact_id)
|
||||
* @return int 0 on success and errno != 0 else
|
||||
*/
|
||||
function save($data=null,$account_id=0)
|
||||
{
|
||||
$this->data_merge($data);
|
||||
|
||||
// if called by read's automatic conversation --> dont change the email of the account (if set)
|
||||
if (!$this->data['owner'] && $account_id &&
|
||||
($email = $GLOBALS['egw']->accounts->id2name($account_id,'account_email')) && $data['email'] != $email)
|
||||
{
|
||||
if (!$data['email_home']) $data['email_home'] = $data['email'];
|
||||
$data['email'] = $email;
|
||||
}
|
||||
if (!($error = parent::save()) && !$this->data['owner']) // successfully saved an account --> sync our data in the account-table
|
||||
{
|
||||
if (!$account_id && !($account_id = $GLOBALS['egw']->accounts->name2id($this->data['id'],'person_id')) &&
|
||||
// try find a matching account for migration
|
||||
!($account_id = $GLOBALS['egw']->accounts->name2id($this->data['n_given'].' '.$this->data['n_family'],'account_fullname')))
|
||||
{
|
||||
// ToDo create new account
|
||||
}
|
||||
// as the account object has no function to just read a record and NOT override it's internal data,
|
||||
// we have to instanciate a new object and can NOT use $GLOBALS['egw']->accounts !!!
|
||||
$account =& new accounts($account_id,'u');
|
||||
$account->read_repository();
|
||||
|
||||
if (!$account->data['account_id']) return false; // account not found
|
||||
|
||||
foreach(array(
|
||||
'n_family' => 'lastname',
|
||||
'n_given' => 'firstname',
|
||||
'email' => 'email',
|
||||
'id' => 'person_id',
|
||||
) as $c_name => $a_name)
|
||||
{
|
||||
$account->data[$a_name] = $this->data[$c_name];
|
||||
}
|
||||
$account->save_repository();
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ class uicontacts extends bocontacts
|
||||
var $private_addressbook = false;
|
||||
var $org_views;
|
||||
|
||||
// var $config = array('call_link'=>'skype:%1?call','call_popup'=>''); // popup wxh, eg. 640x480
|
||||
var $config;
|
||||
|
||||
function uicontacts($contact_app='addressbook')
|
||||
{
|
||||
@ -69,6 +69,8 @@ class uicontacts extends bocontacts
|
||||
// our javascript
|
||||
// to be moved in a seperate file if rewrite is over
|
||||
$GLOBALS['egw_info']['flags']['java_script'] .= $this->js();
|
||||
|
||||
$this->config =& $GLOBALS['egw_info']['server'];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +85,6 @@ class uicontacts extends bocontacts
|
||||
//echo "<p>uicontacts::index(".print_r($content,true).",'$msg')</p>\n";
|
||||
if (($re_submit = is_array($content)))
|
||||
{
|
||||
// $msg = $content['msg'];
|
||||
$do_email = $content['do_email'];
|
||||
|
||||
if (isset($content['nm']['rows']['delete'])) // handle a single delete like delete with the checkboxes
|
||||
@ -130,8 +131,6 @@ class uicontacts extends bocontacts
|
||||
{
|
||||
$content['nm'] = array(
|
||||
'get_rows' => 'addressbook.uicontacts.get_rows', // I method/callback to request the data for the rows eg. 'notes.bo.get_rows'
|
||||
'header_left' => $do_email ? 'addressbook.email.left' : 'addressbook.index.left', // I template to show right of the range-value, right-aligned (optional)
|
||||
// 'header_right' => 'addressbook.index.right', // I template to show right of the range-value, right-aligned (optional)
|
||||
'bottom_too' => false, // I show the nextmatch-line (arrows, filters, search, ...) again after the rows
|
||||
'never_hide' => True, // I never hide the nextmatch-line if less then maxmatch entrie
|
||||
'start' => 0, // IO position in list
|
||||
@ -156,10 +155,19 @@ class uicontacts extends bocontacts
|
||||
$content['nm'] = array_merge($content['nm'],$state);
|
||||
}
|
||||
}
|
||||
if ($do_email && !$re_submit)
|
||||
if ($do_email)
|
||||
{
|
||||
$content['nm']['to'] = 'to';
|
||||
$content['nm']['search'] = '@';
|
||||
if (!$re_submit)
|
||||
{
|
||||
$content['nm']['to'] = 'to';
|
||||
$content['nm']['search'] = '@';
|
||||
}
|
||||
$content['nm']['header_left'] = 'addressbook.email.left';
|
||||
}
|
||||
// Organisation stuff is not (yet) availible with ldap
|
||||
elseif($GLOBALS['egw_info']['server']['contact_repository'] != 'ldap')
|
||||
{
|
||||
$content['nm']['header_left'] = 'addressbook.index.left';
|
||||
}
|
||||
$sel_options = array(
|
||||
'filter' => $this->get_addressbooks(EGW_ACL_READ,lang('All')),
|
||||
@ -510,11 +518,12 @@ class uicontacts extends bocontacts
|
||||
$rows = parent::search($query['search'],$id_only ? array('id','org_name','n_family','n_given','n_fileas') : false,
|
||||
$order,'','%',false,'OR',array((int)$query['start'],(int) $query['num_rows']),$query['col_filter']);
|
||||
|
||||
if (!$id_only && $this->prefs['custom_colum'] != 'never' && $rows) // do we need the custom fields
|
||||
// do we need the custom fields
|
||||
if (!$id_only && $this->prefs['custom_colum'] != 'never' && $rows && $this->customfields)
|
||||
{
|
||||
foreach((array) $rows as $n => $val)
|
||||
{
|
||||
if ($val) $ids[] = $val['id'];
|
||||
if ($val && (int)$val['id']) $ids[] = $val['id'];
|
||||
}
|
||||
if ($ids) $customfields = $this->read_customfields($ids);
|
||||
}
|
||||
@ -614,7 +623,7 @@ class uicontacts extends bocontacts
|
||||
if ($row[$name]) $homeaddress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// disable photo column, if view contains no photo(s)
|
||||
if (!$photos || $this->prefs['photo_column'] == 'never') $rows['no_photo'] = '1';
|
||||
@ -1273,7 +1282,7 @@ $readonlys['button[vcard]'] = true;
|
||||
{
|
||||
if (!$number || !$this->config['call_link']) return false;
|
||||
|
||||
$link = str_replace('%1',$number,$this->config['call_link']);
|
||||
$link = str_replace('%1',urlencode($number),$this->config['call_link']);
|
||||
}
|
||||
|
||||
function js()
|
||||
|
28
addressbook/inc/hook_config.inc.php
Normal file
28
addressbook/inc/hook_config.inc.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Addressbook - configuration
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @package addressbook
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id: class.bocontacts.inc.php 21831 2006-06-14 16:53:14Z ralfbecker $
|
||||
*/
|
||||
|
||||
function contact_repositories($config)
|
||||
{
|
||||
$repositories = array('sql' => 'SQL');
|
||||
// check account-repository, contact-repository LDAP is only availible for account-repository == ldap
|
||||
if ($config['account_repository'] == 'ldap' || !$config['account_repository'] && $config['auth_type'] == 'ldap')
|
||||
{
|
||||
$repositories['ldap'] = 'LDAP';
|
||||
$repositories['sql-ldap'] = 'SQL --> LDAP ('.lang('read only').')';
|
||||
}
|
||||
$options = '';
|
||||
foreach($repositories as $repo => $label)
|
||||
{
|
||||
$options .= '<option value="'.$repo.'"'.($config['contact_repository'] == $repo ? ' selected="1">' : '>').
|
||||
$label."</option>\n";
|
||||
}
|
||||
return $options;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -14,7 +14,7 @@
|
||||
/* Basic information about this app */
|
||||
$setup_info['addressbook']['name'] = 'addressbook';
|
||||
$setup_info['addressbook']['title'] = 'Addressbook';
|
||||
$setup_info['addressbook']['version'] = '1.3.001';
|
||||
$setup_info['addressbook']['version'] = '1.3.002';
|
||||
$setup_info['addressbook']['app_order'] = 4;
|
||||
$setup_info['addressbook']['enable'] = 1;
|
||||
|
||||
@ -32,21 +32,20 @@
|
||||
$setup_info['addressbook']['maintainer'] = 'eGroupWare coreteam';
|
||||
$setup_info['addressbook']['maintainer_email'] = 'egroupware-developers@lists.sourceforge.net';
|
||||
|
||||
$setup_info['addressbook']['tables'][] = 'egw_addressbook';
|
||||
$setup_info['addressbook']['tables'][] = 'egw_addressbook_extra';
|
||||
$setup_info['addressbook']['tables'] = array(); // addressbook tables are in phpgwapi!
|
||||
|
||||
/* The hooks this app includes, needed for hooks registration */
|
||||
$setup_info['addressbook']['hooks']['admin'] = 'addressbook.contacts_admin_prefs.all_hooks';
|
||||
$setup_info['addressbook']['hooks']['preferences'] = 'addressbook.contacts_admin_prefs.all_hooks';
|
||||
$setup_info['addressbook']['hooks']['sidebox_menu'] = 'addressbook.contacts_admin_prefs.all_hooks';
|
||||
$setup_info['addressbook']['hooks']['settings'] = 'addressbook.contacts_admin_prefs.settings';
|
||||
$setup_info['addressbook']['hooks'][] = 'config_validate';
|
||||
$setup_info['addressbook']['hooks'][] = 'home';
|
||||
$setup_info['addressbook']['hooks']['editaccount'] = 'addressbook.bocontacts.editaccount';
|
||||
$setup_info['addressbook']['hooks']['deleteaccount'] = 'addressbook.bocontacts.deleteaccount';
|
||||
$setup_info['addressbook']['hooks'][] = 'notifywindow';
|
||||
$setup_info['addressbook']['hooks']['search_link'] = 'addressbook.bocontacts.search_link';
|
||||
$setup_info['addressbook']['hooks']['edit_user'] = 'addressbook.contacts_admin_prefs.edit_user';
|
||||
$setup_info['addressbook']['hooks'][] = 'config';
|
||||
|
||||
/* Dependencies for this app to work */
|
||||
$setup_info['addressbook']['depends'][] = array(
|
||||
@ -58,3 +57,4 @@
|
||||
'versions' => Array('1.0.0','1.0.1','1.2','1.3')
|
||||
);
|
||||
|
||||
|
||||
|
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* -------------------------------------------- *
|
||||
* 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$
|
||||
// $Source$
|
||||
|
||||
$phpgw_baseline = array(
|
||||
'egw_addressbook' => array(
|
||||
'fd' => array(
|
||||
'id' => array('type' => 'auto','nullable' => False),
|
||||
'lid' => array('type' => 'varchar','precision' => '32'),
|
||||
'tid' => array('type' => 'char','precision' => '1'),
|
||||
'owner' => array('type' => 'int','precision' => '8'),
|
||||
'access' => array('type' => 'varchar','precision' => '7'),
|
||||
'cat_id' => array('type' => 'varchar','precision' => '32'),
|
||||
'fn' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_family' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_given' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_middle' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_prefix' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_suffix' => array('type' => 'varchar','precision' => '64'),
|
||||
'sound' => array('type' => 'varchar','precision' => '64'),
|
||||
'bday' => array('type' => 'varchar','precision' => '32'),
|
||||
'note' => array('type' => 'text'),
|
||||
'tz' => array('type' => 'varchar','precision' => '8'),
|
||||
'geo' => array('type' => 'varchar','precision' => '32'),
|
||||
'url' => array('type' => 'varchar','precision' => '128'),
|
||||
'pubkey' => array('type' => 'text'),
|
||||
'org_name' => array('type' => 'varchar','precision' => '64'),
|
||||
'org_unit' => array('type' => 'varchar','precision' => '64'),
|
||||
'title' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_street' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_locality' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_region' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_postalcode' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_countryname' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_type' => array('type' => 'varchar','precision' => '32'),
|
||||
'label' => array('type' => 'text'),
|
||||
'adr_two_street' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_locality' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_region' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_postalcode' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_countryname' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_type' => array('type' => 'varchar','precision' => '32'),
|
||||
'tel_work' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_home' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_voice' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_fax' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_msg' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_cell' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_pager' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_bbs' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_modem' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_car' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_isdn' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_video' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_prefer' => array('type' => 'varchar','precision' => '32'),
|
||||
'email' => array('type' => 'varchar','precision' => '64'),
|
||||
'email_type' => array('type' => 'varchar','precision' => '32','default' => 'INTERNET'),
|
||||
'email_home' => array('type' => 'varchar','precision' => '64'),
|
||||
'email_home_type' => array('type' => 'varchar','precision' => '32','default' => 'INTERNET'),
|
||||
'last_mod' => array('type' => 'int','precision' => '8','nullable' => False)
|
||||
),
|
||||
'pk' => array('id'),
|
||||
'fk' => array(),
|
||||
'ix' => array(array('tid','owner','access','n_family','n_given'),array('tid','cat_id','owner','access','n_family')),
|
||||
'uc' => array()
|
||||
),
|
||||
'egw_addressbook_extra' => array(
|
||||
'fd' => array(
|
||||
'contact_id' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'contact_owner' => array('type' => 'int','precision' => '8'),
|
||||
'contact_name' => array('type' => 'varchar','precision' => '255','nullable' => False),
|
||||
'contact_value' => array('type' => 'text')
|
||||
),
|
||||
'pk' => array('contact_id','contact_name'),
|
||||
'fk' => array(),
|
||||
'ix' => array(),
|
||||
'uc' => array()
|
||||
),
|
||||
);
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* -------------------------------------------- *
|
||||
* 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$ */
|
||||
|
||||
$phpgw_baseline = array(
|
||||
'egw_addressbook' => array(
|
||||
'fd' => array(
|
||||
'contact_id' => array('type' => 'auto','nullable' => False),
|
||||
'contact_tid' => array('type' => 'char','precision' => '1','default' => 'n'),
|
||||
'contact_owner' => array('type' => 'int','precision' => '8','nullable' => False),
|
||||
'contact_private' => array('type' => 'int','precision' => '1','default' => '0'),
|
||||
'cat_id' => array('type' => 'varchar','precision' => '32'),
|
||||
'n_family' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_given' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_middle' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_prefix' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_suffix' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_fn' => array('type' => 'varchar','precision' => '128'),
|
||||
'n_fileas' => array('type' => 'varchar','precision' => '255'),
|
||||
'contact_bday' => array('type' => 'varchar','precision' => '10'),
|
||||
'org_name' => array('type' => 'varchar','precision' => '64'),
|
||||
'org_unit' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_title' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_role' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_assistent' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_room' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_street' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_street2' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_locality' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_region' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_postalcode' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_countryname' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_label' => array('type' => 'text'),
|
||||
'adr_two_street' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_street2' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_locality' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_region' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_postalcode' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_countryname' => array('type' => 'varchar','precision' => '64'),
|
||||
'tel_work' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_cell' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_fax' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_assistent' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_car' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_pager' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_home' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_fax_home' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_cell_private' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_other' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_prefer' => array('type' => 'varchar','precision' => '32'),
|
||||
'contact_email' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_email_home' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_url' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_url_home' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_freebusy_uri' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_calendar_uri' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_note' => array('type' => 'text'),
|
||||
'contact_tz' => array('type' => 'varchar','precision' => '8'),
|
||||
'contact_geo' => array('type' => 'varchar','precision' => '32'),
|
||||
'contact_pubkey' => array('type' => 'text'),
|
||||
'contact_created' => array('type' => 'int','precision' => '8'),
|
||||
'contact_creator' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'contact_modified' => array('type' => 'int','precision' => '8','nullable' => False),
|
||||
'contact_modifier' => array('type' => 'int','precision' => '4'),
|
||||
'contact_jpegphoto' => array('type' => 'blob'),
|
||||
),
|
||||
'pk' => array('contact_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array('cat_id','contact_owner','n_fileas',array('n_family','n_given'),array('n_given','n_family'),array('org_name','n_family','n_given')),
|
||||
'uc' => array()
|
||||
),
|
||||
'egw_addressbook_extra' => array(
|
||||
'fd' => array(
|
||||
'contact_id' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'contact_owner' => array('type' => 'int','precision' => '8'),
|
||||
'contact_name' => array('type' => 'varchar','precision' => '255','nullable' => False),
|
||||
'contact_value' => array('type' => 'text')
|
||||
),
|
||||
'pk' => array('contact_id','contact_name'),
|
||||
'fk' => array(),
|
||||
'ix' => array(),
|
||||
'uc' => array()
|
||||
)
|
||||
);
|
@ -1,168 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Setup *
|
||||
* http://www.eGroupWare.org *
|
||||
* Created by eTemplates DB-Tools written by ralfbecker@outdoor-training.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$ */
|
||||
|
||||
$test[] = '1.0.0';
|
||||
function addressbook_upgrade1_0_0()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->RenameTable('phpgw_addressbook','egw_addressbook');
|
||||
$GLOBALS['egw_setup']->oProc->RenameTable('phpgw_addressbook_extra','egw_addressbook_extra');
|
||||
|
||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '1.2';
|
||||
}
|
||||
|
||||
$test[] = '1.2';
|
||||
function addressbook_upgrade1_2()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->RefreshTable('egw_addressbook',array(
|
||||
'fd' => array(
|
||||
'contact_id' => array('type' => 'auto','nullable' => False),
|
||||
'contact_tid' => array('type' => 'char','precision' => '1','default' => 'n'),
|
||||
'contact_owner' => array('type' => 'int','precision' => '8','nullable' => False),
|
||||
'contact_private' => array('type' => 'int','precision' => '1','default' => '0'),
|
||||
'cat_id' => array('type' => 'varchar','precision' => '32'),
|
||||
'n_family' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_given' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_middle' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_prefix' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_suffix' => array('type' => 'varchar','precision' => '64'),
|
||||
'n_fn' => array('type' => 'varchar','precision' => '128'),
|
||||
'n_fileas' => array('type' => 'varchar','precision' => '255'),
|
||||
'contact_bday' => array('type' => 'varchar','precision' => '10'),
|
||||
'org_name' => array('type' => 'varchar','precision' => '64'),
|
||||
'org_unit' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_title' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_role' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_assistent' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_room' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_street' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_street2' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_locality' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_region' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_postalcode' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_countryname' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_label' => array('type' => 'text'),
|
||||
'adr_two_street' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_street2' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_locality' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_region' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_postalcode' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_two_countryname' => array('type' => 'varchar','precision' => '64'),
|
||||
'tel_work' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_cell' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_fax' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_assistent' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_car' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_pager' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_home' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_fax_home' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_cell_private' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_other' => array('type' => 'varchar','precision' => '40'),
|
||||
'tel_prefer' => array('type' => 'varchar','precision' => '32'),
|
||||
'contact_email' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_email_home' => array('type' => 'varchar','precision' => '64'),
|
||||
'contact_url' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_url_home' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_freebusy_uri' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_calendar_uri' => array('type' => 'varchar','precision' => '128'),
|
||||
'contact_note' => array('type' => 'text'),
|
||||
'contact_tz' => array('type' => 'varchar','precision' => '8'),
|
||||
'contact_geo' => array('type' => 'varchar','precision' => '32'),
|
||||
'contact_pubkey' => array('type' => 'text'),
|
||||
'contact_created' => array('type' => 'int','precision' => '8'),
|
||||
'contact_creator' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'contact_modified' => array('type' => 'int','precision' => '8','nullable' => False),
|
||||
'contact_modifier' => array('type' => 'int','precision' => '4'),
|
||||
'contact_jpegphoto' => array('type' => 'blob'),
|
||||
),
|
||||
'pk' => array('contact_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array('cat_id','contact_owner','n_fileas',array('n_family','n_given'),array('n_given','n_family'),array('org_name','n_family','n_given')),
|
||||
'uc' => array()
|
||||
),array(
|
||||
// new colum prefix
|
||||
'contact_id' => 'id',
|
||||
'contact_tid' => 'tid',
|
||||
'contact_owner' => 'owner',
|
||||
'contact_private' => "CASE access WHEN 'private' THEN 1 ELSE 0 END",
|
||||
'n_fn' => 'fn',
|
||||
'contact_title' => 'title',
|
||||
'contact_bday' => 'bday',
|
||||
'contact_note' => 'note',
|
||||
'contact_tz' => 'tz',
|
||||
'contact_geo' => 'geo',
|
||||
'contact_url' => 'url',
|
||||
'contact_pubkey' => 'pubkey',
|
||||
'contact_label' => 'label',
|
||||
'contact_email' => 'email',
|
||||
'contact_email_home' => 'email_home',
|
||||
'contact_modified' => 'last_mod',
|
||||
// remove stupid old default values, rename phone-numbers, tel_bbs and tel_video are droped
|
||||
'tel_work' => "CASE tel_work WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_work END",
|
||||
'tel_cell' => "CASE tel_cell WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_cell END",
|
||||
'tel_fax' => "CASE tel_fax WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_fax END",
|
||||
'tel_assistent' => "CASE tel_msg WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_msg END",
|
||||
'tel_car' => "CASE tel_car WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_car END",
|
||||
'tel_pager' => "CASE tel_pager WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_pager END",
|
||||
'tel_home' => "CASE tel_home WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_home END",
|
||||
'tel_fax_home' => "CASE tel_modem WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_modem END",
|
||||
'tel_cell_private' => "CASE tel_isdn WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_isdn END",
|
||||
'tel_other' => "CASE tel_voice WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_voice END",
|
||||
'tel_prefer' => "CASE tel_prefer WHEN 'tel_voice' THEN 'tel_other' WHEN 'tel_msg' THEN 'tel_assistent' WHEN 'tel_modem' THEN 'tel_fax_home' WHEN 'tel_isdn' THEN 'tel_cell_private' WHEN 'ophone' THEN 'tel_other' ELSE tel_prefer END",
|
||||
// set creator from owner
|
||||
'contact_creator' => 'owner',
|
||||
// set contact_fileas from org_name, n_family and n_given
|
||||
'n_fileas' => "CASE WHEN org_name='' THEN (".
|
||||
($name_sql = "CASE WHEN n_given='' THEN n_family ELSE ".$GLOBALS['egw_setup']->db->concat('n_family',"', '",'n_given').' END').
|
||||
") ELSE (CASE WHEN n_family='' THEN org_name ELSE ".$GLOBALS['egw_setup']->db->concat('org_name',"': '",$name_sql).' END) END',
|
||||
|
||||
));
|
||||
|
||||
// migrate values saved in custom fields to the new table
|
||||
$db2 = clone($GLOBALS['egw_setup']->db);
|
||||
$GLOBALS['egw_setup']->db->select('egw_addressbook_extra','contact_id,contact_name,contact_value',
|
||||
"contact_name IN ('ophone','address2','address3','freebusy_url') AND contact_value != '' AND NOT contact_value IS NULL"
|
||||
,__LINE__,__FILE__,false,'','addressbook');
|
||||
$old2new = array(
|
||||
'ophone' => 'tel_other',
|
||||
'address2' => 'adr_one_street2',
|
||||
'address3' => 'adr_two_street2',
|
||||
'freebusy_url' => 'contact_freebusy_uri',
|
||||
);
|
||||
while (($row = $GLOBALS['egw_setup']->db->row(true)))
|
||||
{
|
||||
$db2->update('egw_addressbook',array($old2new[$row['contact_name']] => $row['contact_value']),array(
|
||||
'contact_id' => $row['contact_id'],
|
||||
'('.$old2new[$row['contact_name']].'IS NULL OR '.$old2new[$row['contact_name']]."='')",
|
||||
),__LINE__,__FILE__,'addressbook');
|
||||
}
|
||||
// delete the not longer used custom fields plus rubish from old bugs
|
||||
$GLOBALS['egw_setup']->db->delete('egw_addressbook_extra',"contact_name IN ('ophone','address2','address3','freebusy_url','cat_id','tid','lid','id','ab_id','access','owner','rights')".
|
||||
" OR contact_value='' OR contact_value IS NULL".
|
||||
($db2->capabilities['subqueries'] ? " OR contact_id NOT IN (SELECT contact_id FROM egw_addressbook)" : ''),
|
||||
__LINE__,__FILE__,'addressbook');
|
||||
|
||||
// change the m/d/Y birthday format to Y-m-d
|
||||
$GLOBALS['egw_setup']->db->select('egw_addressbook','contact_id,contact_bday',"contact_bday != ''",
|
||||
__LINE__,__FILE__,false,'','addressbook');
|
||||
while (($row = $GLOBALS['egw_setup']->db->row(true)))
|
||||
{
|
||||
list($m,$d,$y) = explode('/',$row['contact_bday']);
|
||||
$db2->update('egw_addressbook',array(
|
||||
'contact_bday' => sprintf('%04d-%02d-%02d',$y,$m,$d)
|
||||
),array(
|
||||
'contact_id' => $row['contact_id'],
|
||||
),__LINE__,__FILE__,'addressbook');
|
||||
}
|
||||
return $GLOBALS['setup_info']['addressbook']['currentver'] = '1.3.001';
|
||||
}
|
@ -11,28 +11,51 @@
|
||||
<!-- END header -->
|
||||
<!-- BEGIN body -->
|
||||
<tr class="th">
|
||||
<td colspan="2"> <b>{lang_Addressbook}/{lang_Contact_Settings}</b></td>
|
||||
<td colspan="2"> <b>{lang_Telephony_integration}</b></td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td> {lang_URL_to_link_telephone_numbers_to_(use_%1_for_the_number)}:</td>
|
||||
<td><input name="newsettings[call_link]" value="{value_call_link}" size="40"></td>
|
||||
</tr>
|
||||
<tr class="row_off">
|
||||
<td>{lang_Select_where_you_want_to_store_/_retrieve_contacts}.</td>
|
||||
<td> {lang_Size_of_popup_(WxH,_eg.400x300,_if_a_popup_should_be_used)}:</td>
|
||||
<td><input name="newsettings[call_popup]" value="{value_call_popup}" size="10"></td>
|
||||
</tr>
|
||||
<tr class="th">
|
||||
<td colspan="2"> <b>{lang_Contact_repository}</b></td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td> {lang_Select_where_you_want_to_store_/_retrieve_contacts}:</td>
|
||||
<td>
|
||||
<select name="newsettings[contact_repository]">
|
||||
<option value="sql" {selected_contact_repository_sql}>SQL</option>
|
||||
<option value="ldap" {selected_contact_repository_ldap}>LDAP</option>
|
||||
{hook_contact_repositories}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row_off">
|
||||
<td colspan="2"> {lang_You_can_only_use_LDAP_as_contact_repository_if_the_accounts_are_stored_in_LDAP_too!}</td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td>{lang_LDAP_host_for_contacts}:</td>
|
||||
<td> {lang_Account_repository}:</td>
|
||||
<td>
|
||||
<b><script>document.write('{value_account_reposiory}' == 'ldap' || '{value_account_reposiory}' == '' && '{value_auth_type}' == 'ldap' ? 'LDAP' : 'SQL');</script></b>
|
||||
({lang_Can_be_changed_via_Setup_>>_Configuration})
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="th">
|
||||
<td colspan="2"> <b>{lang_LDAP_settings_for_contacts}</b></td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td> {lang_LDAP_host_for_contacts}:</td>
|
||||
<td><input name="newsettings[ldap_contact_host]" value="{value_ldap_contact_host}"></td>
|
||||
</tr>
|
||||
<tr class="row_off">
|
||||
<td>{lang_LDAP_context_for_contacts}:</td>
|
||||
<td> {lang_LDAP_context_for_contacts}:</td>
|
||||
<td><input name="newsettings[ldap_contact_context]" value="{value_ldap_contact_context}" size="40"></td>
|
||||
</tr>
|
||||
<tr class="th">
|
||||
<td colspan="2">
|
||||
{lang_Additional_information_about_using_LDAP_as_contact_repository}:
|
||||
{lang_Additional_information_about_using_LDAP_as_contact_repository}:
|
||||
<a href="addressbook/doc/README" target="_blank">README</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -113,10 +113,10 @@
|
||||
<description id="${row}[adr_two_street2]" no_lang="1"/>
|
||||
</vbox>
|
||||
<vbox orient=",0,0">
|
||||
<description no_lang="1" id="${row}[tel_work]" class="telNumbers" options=",$row_cont[tel_work_link],,,,$row_cont[call_popup]"/>
|
||||
<description id="${row}[tel_cell]" no_lang="1" class="telNumbers" options=",$row_cont[tel_cell_link],,,,$row_cont[call_popup]"/>
|
||||
<description id="${row}[tel_home]" no_lang="1" class="telNumbers" options=",$row_cont[tel_home_link],,,,$row_cont[call_popup]"/>
|
||||
<description id="${row}[tel_prefered]" no_lang="1" options=",$row_cont[tel_prefered_link],,,,$row_cont[call_popup]"/>
|
||||
<description no_lang="1" id="${row}[tel_work]" class="telNumbers" options=",$row_cont[tel_work_link],,,calling,$cont[call_popup]"/>
|
||||
<description id="${row}[tel_cell]" no_lang="1" class="telNumbers" options=",$row_cont[tel_cell_link],,,calling,$cont[call_popup]"/>
|
||||
<description id="${row}[tel_home]" no_lang="1" class="telNumbers" options=",$row_cont[tel_home_link],,,calling,$cont[call_popup]"/>
|
||||
<description id="${row}[tel_prefered]" no_lang="1" options=",$row_cont[tel_prefered_link],,,calling,$cont[call_popup]"/>
|
||||
</vbox>
|
||||
<vbox orient=",0,0">
|
||||
<description options=",,1" class="fixedHeight" no_lang="1" id="${row}[url]"/>
|
||||
|
Loading…
Reference in New Issue
Block a user