forked from extern/egroupware
- readonly LDAP sync (acount-repository SQL --> LDAP) is fully working now
- migration for contacts to LDAP - some general addressbook fixes
This commit is contained in:
parent
ad7972870c
commit
bd7f7f417d
@ -31,10 +31,14 @@ define('ADDRESSBOOK_GROUP',3);
|
||||
class so_ldap
|
||||
{
|
||||
var $data;
|
||||
//var $db_data_cols;
|
||||
//var $db_key_cols;
|
||||
var $groupName = 'Default';
|
||||
|
||||
/**
|
||||
* internal name of the id, gets mapped to uid
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $contacts_id='id';
|
||||
|
||||
/**
|
||||
* @var string $accountName holds the accountname of the current user
|
||||
*/
|
||||
@ -216,7 +220,7 @@ class so_ldap
|
||||
$GLOBALS['egw']->ldap =& CreateObject('phpgwapi.ldap');
|
||||
}
|
||||
// if ldap is NOT the contact repository, we only do accounts and need to use the account-data
|
||||
if ($GLOBALS['egw_info']['server']['contact_repository'] != 'ldap')
|
||||
if (substr($GLOBALS['egw_info']['server']['contact_repository'],-4) != 'ldap') // not (ldap or sql-ldap)
|
||||
{
|
||||
$GLOBALS['egw_info']['server']['ldap_contact_host'] = $GLOBALS['egw_info']['server']['ldap_host'];
|
||||
$GLOBALS['egw_info']['server']['ldap_contact_context'] = $GLOBALS['egw_info']['server']['ldap_context'];
|
||||
@ -264,14 +268,22 @@ class so_ldap
|
||||
/**
|
||||
* reads contact data
|
||||
*
|
||||
* @param string $contact_id contact_id or 'account:'.account_id
|
||||
* @param string/array $contact_id contact_id or array with values for id or account_id
|
||||
* @return array/boolean data if row could be retrived else False
|
||||
*/
|
||||
function read($contact_id)
|
||||
{
|
||||
$contact_id = ldap::quote($contact_id);
|
||||
if (is_array($contact_id) && isset($contact_id['account_id']) || substr($contact_id,0,8) == 'account:')
|
||||
{
|
||||
$filter = 'uidNumber='.(int)(is_array($contact_id) ? $contact_id['account_id'] : substr($contact_id,8));
|
||||
}
|
||||
else
|
||||
{
|
||||
$contact_id = ldap::quote(is_array($contact_id) ? $contact_id['id'] : $contact_id);
|
||||
$filter = "(|(entryUUID=$contact_id)(uid=$contact_id))";
|
||||
}
|
||||
$rows = $this->_searchLDAP($GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||
"(|(entryUUID=$contact_id)(uid=$contact_id))", $this->all_attributes, ADDRESSBOOK_ALL);
|
||||
$filter, $this->all_attributes, ADDRESSBOOK_ALL);
|
||||
|
||||
return $rows ? $rows[0] : false;
|
||||
}
|
||||
@ -305,17 +317,25 @@ class so_ldap
|
||||
}
|
||||
$baseDN = 'cn='. ldap::quote($cn) .','.($data['owner'] < 0 ? $this->sharedContactsDN : $this->personalContactsDN);
|
||||
}
|
||||
elseif ($GLOBALS['egw_info']['user']['apps']['admin'])
|
||||
// only an admin or the user itself is allowed to change the data of an account
|
||||
elseif ($data['account_id'] && ($GLOBALS['egw_info']['user']['apps']['admin'] ||
|
||||
$data['account_id'] == $GLOBALS['egw_info']['user']['account_id']))
|
||||
{
|
||||
// account
|
||||
$baseDN = $GLOBALS['egw_info']['server']['ldap_context'];
|
||||
$cn = false;
|
||||
// we need an admin connection
|
||||
$this->ds = $GLOBALS['egw']->ldap->ldapConnect();
|
||||
|
||||
// for sql-ldap we need to account_lid/uid as id, NOT the contact_id in id!
|
||||
if ($GLOBALS['egw_info']['server']['contact_repository'] == 'sql-ldap')
|
||||
{
|
||||
$data['id'] = $GLOBALS['egw']->accounts->id2name($data['account_id']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true; // only admin is allowd to write accounts!
|
||||
return true; // only admin or the user itself is allowd to write accounts!
|
||||
}
|
||||
|
||||
// check if $baseDN exists. If not create it
|
||||
@ -795,19 +815,19 @@ class so_ldap
|
||||
{
|
||||
// personal addressbook
|
||||
$contact['owner'] = $GLOBALS['egw']->accounts->name2id($matches[1],'account_lid','u');
|
||||
$contact['private'] = true;
|
||||
$contact['private'] = 1;
|
||||
}
|
||||
elseif(preg_match('/cn=([^,]+),'.preg_quote($this->sharedContactsDN).'$/i',$entry['dn'],$matches))
|
||||
{
|
||||
// group addressbook
|
||||
$contact['owner'] = $GLOBALS['egw']->accounts->name2id($matches[1],'account_lid','g');
|
||||
$contact['private'] = false;
|
||||
$contact['private'] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// accounts
|
||||
$contact['owner'] = 0;
|
||||
$contact['private'] = false;
|
||||
$contact['private'] = 0;
|
||||
}
|
||||
foreach(array(
|
||||
'creatorsname' => 'creator',
|
||||
|
@ -219,7 +219,6 @@ class socontacts
|
||||
if ($this->account_repository != $this->contact_repository)
|
||||
{
|
||||
$this->so_accounts =& CreateObject('addressbook.so_ldap');
|
||||
$this->so_accounts->contacts_id = 'id';
|
||||
$this->account_cols_to_search = $this->ldap_search_attributes;
|
||||
}
|
||||
else
|
||||
@ -238,7 +237,6 @@ class socontacts
|
||||
// ToDo: it should be the other way arround, the backend should set the grants it uses
|
||||
$this->somain->grants =& $this->grants;
|
||||
|
||||
$this->somain->contacts_id = 'id';
|
||||
$this->soextra =& CreateObject('etemplate.so_sql');
|
||||
$this->soextra->so_sql('phpgwapi',$this->extra_table);
|
||||
|
||||
@ -265,6 +263,10 @@ class socontacts
|
||||
*/
|
||||
function read_customfields($ids)
|
||||
{
|
||||
if ($this->contact_repository == 'ldap')
|
||||
{
|
||||
return array(); // ldap does not support custom-fields (non-nummeric uid)
|
||||
}
|
||||
foreach($ids as $key => $id)
|
||||
{
|
||||
if (!(int)$id) unset($ids[$key]);
|
||||
@ -327,7 +329,7 @@ class socontacts
|
||||
{
|
||||
// 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']);
|
||||
$contact['id'] = $GLOBALS['egw']->accounts->id2name($contact['account_id']);
|
||||
}
|
||||
ExecMethod('addressbook.so_ldap.delete',$contact);
|
||||
}
|
||||
@ -355,7 +357,15 @@ class socontacts
|
||||
}
|
||||
else
|
||||
{
|
||||
// contact_repository sql-ldap (accounts in ldap) the person_id is the uid (account_lid)
|
||||
// for the sql write here we need to find out the existing contact_id
|
||||
if ($this->contact_repository == 'sql-ldap' && $contact['id'] && !is_numeric($contact['id']) &&
|
||||
$contact['account_id'] && ($old = $this->somain->read(array('account_id' => $contact['account_id']))))
|
||||
{
|
||||
$contact['id'] = $old['id'];
|
||||
}
|
||||
$this->somain->data = $this->data2db($contact);
|
||||
|
||||
if (!($error_nr = $this->somain->save()))
|
||||
{
|
||||
$contact['id'] = $this->somain->data['id'];
|
||||
@ -367,7 +377,7 @@ class socontacts
|
||||
{
|
||||
// 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']);
|
||||
$data['id'] = $GLOBALS['egw']->accounts->id2name($contact['account_id']);
|
||||
}
|
||||
ExecMethod('addressbook.so_ldap.save',$data);
|
||||
}
|
||||
@ -407,10 +417,9 @@ 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'))))
|
||||
if (!is_array($contact_id) && substr($contact_id,0,8) == 'account:')
|
||||
{
|
||||
return false;
|
||||
$contact_id = array('account_id' => (int) substr($contact_id,8));
|
||||
}
|
||||
// read main data
|
||||
$backend =& $this->get_backend($contact_id);
|
||||
@ -418,14 +427,13 @@ class socontacts
|
||||
{
|
||||
return $contact;
|
||||
}
|
||||
// read customfields
|
||||
$keys = array(
|
||||
$this->extra_id => $contact['id'],
|
||||
$this->extra_owner => $contact['owner'],
|
||||
);
|
||||
if ($this->customfields) // try reading customfields only if we have some
|
||||
// try reading customfields only if we have some (none for LDAP!)
|
||||
if ($this->customfields && $this->contact_repository != 'ldap')
|
||||
{
|
||||
$customfields = $this->soextra->search($keys,false);
|
||||
$customfields = $this->soextra->search(array(
|
||||
$this->extra_id => $contact['id'],
|
||||
$this->extra_owner => $contact['owner'],
|
||||
),false);
|
||||
foreach ((array)$customfields as $field)
|
||||
{
|
||||
$contact['#'.$field[$this->extra_key]] = $field[$this->extra_value];
|
||||
@ -862,4 +870,69 @@ error_log("socontacts::search(".print_r($criteria,true).",'$only_keys','$order_b
|
||||
//echo "unsupported fields=";_debug_array(array_diff($all_fields,$supported_fields));
|
||||
return array_diff($all_fields,$supported_fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates an SQL contact storage to LDAP or SQL-LDAP
|
||||
*
|
||||
* @param string $type "contacts" (default), "contacts+accounts" or "contacts+accounts-back" (sql-ldap!)
|
||||
*/
|
||||
function migrate2ldap($type)
|
||||
{
|
||||
$sql_contacts =& CreateObject('addressbook.socontacts_sql');
|
||||
$ldap_contacts =& CreateObject('addressbook.so_ldap');
|
||||
|
||||
$start = $n = 0;
|
||||
$num = 100;
|
||||
while (($contacts = $sql_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
||||
array($start,$num),$type != 'contacts,accounts' ? array('contact_owner != 0') : false)))
|
||||
{
|
||||
foreach($contacts as $contact)
|
||||
{
|
||||
if ($contact['account_id']) $contact['id'] = $GLOBALS['egw']->accounts->id2name($contact['account_id']);
|
||||
|
||||
$ldap_contacts->data = $contact;
|
||||
$n++;
|
||||
if (!($err = $ldap_contacts->save()))
|
||||
{
|
||||
echo '<p style="margin: 0px;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '')." --> LDAP</p>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<p style="margin: 0px; color: red;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '').': '.$err."</p>\n";
|
||||
}
|
||||
}
|
||||
$start += $num;
|
||||
}
|
||||
if ($type == 'contacts,accounts-back') // migrate the accounts to sql
|
||||
{
|
||||
foreach($ldap_contacts->search(false,false,'n_family,n_given','','',false,'AND',
|
||||
false,array('owner' => 0)) as $contact)
|
||||
{
|
||||
if ($contact['jpegphoto']) // photo is NOT read by LDAP backend on search, need to do an extra read
|
||||
{
|
||||
$contact = $ldap_contacts->read($contact['id']);
|
||||
}
|
||||
unset($contact['id']); // ldap uid/account_lid
|
||||
if ($contact['account_id'] && ($old = $sql_contacts->read(array('account_id' => $contact['account_id']))))
|
||||
{
|
||||
$contact['id'] = $old['id'];
|
||||
}
|
||||
$sql_contacts->data = $contact;
|
||||
|
||||
$n++;
|
||||
if (!($err = $sql_contacts->save()))
|
||||
{
|
||||
echo '<p style="margin: 0px;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '')." --> SQL (".lang('User').")</p>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<p style="margin: 0px; color: red;">'.$n.': '.$contact['n_fn'].
|
||||
($contact['org_name'] ? ' ('.$contact['org_name'].')' : '').': '.$err."</p>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,13 @@ class socontacts_sql extends so_sql
|
||||
var $account_repository = 'sql';
|
||||
var $contact_repository = 'sql';
|
||||
|
||||
/**
|
||||
* internal name of the id, gets mapped to uid
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $contacts_id='id';
|
||||
|
||||
function socontacts_sql()
|
||||
{
|
||||
$this->so_sql('phpgwapi','egw_addressbook',null,'contact_'); // calling the constructor of the extended class
|
||||
@ -219,7 +226,7 @@ class socontacts_sql extends so_sql
|
||||
unset($filter['cat_id']);
|
||||
}
|
||||
// add filter for read ACL in sql, if user is NOT the owner of the addressbook
|
||||
if (!(isset($filter['owner']) && $filter['owner'] == $GLOBALS['egw_info']['user']['account_id']))
|
||||
if (isset($this->grants) && !(isset($filter['owner']) && $filter['owner'] == $GLOBALS['egw_info']['user']['account_id']))
|
||||
{
|
||||
// we have no private grants in addressbook at the moment, they have then to be added here too
|
||||
if (isset($filter['owner']))
|
||||
|
@ -31,6 +31,7 @@ class uicontacts extends bocontacts
|
||||
'index' => True,
|
||||
'photo' => True,
|
||||
'emailpopup'=> True,
|
||||
'migrate2ldap' => True,
|
||||
);
|
||||
var $prefs;
|
||||
/**
|
||||
@ -1350,4 +1351,22 @@ $readonlys['button[vcard]'] = true;
|
||||
}
|
||||
</script>';
|
||||
}
|
||||
|
||||
function migrate2ldap()
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('Addressbook').' - '.lang('Migration to LDAP');
|
||||
$GLOBALS['egw']->common->egw_header();
|
||||
parse_navbar();
|
||||
|
||||
if (!$GLOBALS['egw_info']['user']['apps']['admin'])
|
||||
{
|
||||
echo '<h1>'.lang('Permission denied !!!')."</h1>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::migrate2ldap($_GET['type']);
|
||||
echo '<p style="margin-top: 20px;"><b>'.lang('Migration finished')."</b></p>\n";
|
||||
}
|
||||
$GLOBALS['egw']->common->egw_footer();
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ contact id addressbook de Kontakt ID
|
||||
contact repository admin de Speicherort Kontakte
|
||||
contact saved addressbook de Kontakt gespeichert
|
||||
contact settings admin de Kontakt Einstellungen
|
||||
contacts and account contact-data to ldap admin de Kontakte und Kontaktdaten der Benutzer nach LDAP
|
||||
contacts to ldap admin de Kontakte nach LDAP
|
||||
contacts to ldap, account contact-data to sql admin de Kontakte nach LDAP, Kontaktdaten der Benutzer nach SQL
|
||||
copied by %1, from record #%2. addressbook de Kopiert von %1, vom Datensatz Nr. %2.
|
||||
copy a contact and edit the copy addressbook de Kopiert einen Kontakt und bearbeitet dann die Kopie
|
||||
country common de Land
|
||||
@ -125,6 +128,7 @@ field name addressbook de Feldname
|
||||
fields for the csv export addressbook de Felder für den CSV Export
|
||||
fields to show in address list addressbook de Felder, die in der Adressliste angezeigt werden sollen
|
||||
fieldseparator addressbook de Feldtrenner
|
||||
for read only ldap admin de für nur lesendes LDAP
|
||||
freebusy uri addressbook de Freebusy URI
|
||||
full name addressbook de vollständiger Name
|
||||
geo addressbook de GEO
|
||||
@ -140,6 +144,7 @@ home state addressbook de Bundesland privat
|
||||
home street addressbook de Straße privat
|
||||
home zip code addressbook de PLZ privat
|
||||
icon addressbook de Icon
|
||||
if accounts are already in ldap admin de wenn die Benutzer bereits im LDAP sind
|
||||
import addressbook de Import
|
||||
import contacts addressbook de Kontakte importieren
|
||||
import csv-file into addressbook addressbook de Import CSV-Datei ins Adressbuch
|
||||
@ -169,6 +174,8 @@ locations addressbook de Standorte
|
||||
mark records as private addressbook de Eintrag als Privat kennzeichnen
|
||||
message phone addressbook de Anrufbeantworter
|
||||
middle name addressbook de Zweiter Vorname
|
||||
migration finished addressbook de Migration beendet
|
||||
migration to ldap admin de Migration nach LDAP
|
||||
mobile addressbook de Mobil
|
||||
mobile phone addressbook de Mobiltelefon
|
||||
modem phone addressbook de Modem
|
||||
@ -214,6 +221,7 @@ select a view addressbook de Eine Ansicht ausw
|
||||
select addressbook type addressbook de Typ des Adressbuchs auswählen
|
||||
select all addressbook de Alles auswählen
|
||||
select an action or addressbook to move to addressbook de Befehl oder Adressbuch zum Verschieben auswählen
|
||||
select migration type admin de Migrationstyp auswählen
|
||||
select multiple contacts for a further action addressbook de Mehrere Adressen für weiteren Befehl auswählen
|
||||
select phone number as prefered way of contact addressbook de Telefonnummer als präferierten Kontaktweg auswählen
|
||||
select the type of conversion addressbook de Typ der Umwandlung auswählen
|
||||
@ -224,6 +232,7 @@ show a column for %1 addressbook de Zeige eine %1 Spalte
|
||||
show birthday reminders on main screen addressbook de Geburtstagserinnerungen auf der Startseite anzeigen
|
||||
show the contacts of this organisation addressbook de Kontakte dieser Organisation anzeigen
|
||||
size of popup (wxh, eg.400x300, if a popup should be used) admin de Größe des Popup (WxH, zB. 400x300, falls ein Popup verwendet werden soll)
|
||||
start admin de Starten
|
||||
startrecord addressbook de Startdatensatz
|
||||
state common de Bundesland
|
||||
street common de Straße
|
||||
@ -244,6 +253,7 @@ update a single entry by passing the fields. addressbook de Aktualisiert einen e
|
||||
upload or delete the photo addressbook de Foto hochladen oder löschen
|
||||
url to link telephone numbers to (use %1 for the number) admin de URL mit denen Telefonnummern verlinkt werden sollen (%1 für die Nummber verwenden)
|
||||
use country list addressbook de Länderliste benutzen
|
||||
use setup for a full account-migration admin de für eine komplette Benutzer Migration setup verwenden
|
||||
used for links and for the own sorting of the list addressbook de wird für Verküpfungen und die eigene Sortierung der Liste benützt
|
||||
vcard common de VCard
|
||||
vcards require a first name entry. addressbook de VCards benötigen einen Vornamen.
|
||||
|
@ -70,6 +70,9 @@ contact id addressbook en Contact ID
|
||||
contact repository admin en Contact repository
|
||||
contact saved addressbook en Contact saved
|
||||
contact settings admin en Contact Settings
|
||||
contacts and account contact-data to ldap admin en contacts and account contact-data to LDAP
|
||||
contacts to ldap admin en contacts to LDAP
|
||||
contacts to ldap, account contact-data to sql admin en contacts to LDAP, account contact-data to SQL
|
||||
copied by %1, from record #%2. addressbook en Copied by %1, from record #%2.
|
||||
copy a contact and edit the copy addressbook en Copy a contact and edit the copy
|
||||
country common en Country
|
||||
@ -125,6 +128,7 @@ field name addressbook en Field Name
|
||||
fields for the csv export addressbook en Fields for the CSV export
|
||||
fields to show in address list addressbook en Fields to show in address list
|
||||
fieldseparator addressbook en Fieldseparator
|
||||
for read only ldap admin en for read only LDAP
|
||||
freebusy uri addressbook en Freebusy URI
|
||||
full name addressbook en Full Name
|
||||
geo addressbook en GEO
|
||||
@ -140,6 +144,7 @@ home state addressbook en Home State
|
||||
home street addressbook en Home Street
|
||||
home zip code addressbook en Home ZIP Code
|
||||
icon addressbook en Icon
|
||||
if accounts are already in ldap admin en if accounts are already in LDAP
|
||||
import addressbook en Import
|
||||
import contacts addressbook en Import Contacts
|
||||
import csv-file into addressbook addressbook en Import CSV-File into Addressbook
|
||||
@ -169,6 +174,8 @@ locations addressbook en locations
|
||||
mark records as private addressbook en Mark records as private
|
||||
message phone addressbook en Message Phone
|
||||
middle name addressbook en Middle Name
|
||||
migration finished addressbook en Migration finished
|
||||
migration to ldap admin en Migration to LDAP
|
||||
mobile addressbook en Mobile
|
||||
mobile phone addressbook en Mobile Phone
|
||||
modem phone addressbook en Modem Phone
|
||||
@ -214,6 +221,7 @@ select a view addressbook en Select a view
|
||||
select addressbook type addressbook en Select addressbook type
|
||||
select all addressbook en Select all
|
||||
select an action or addressbook to move to addressbook en Select an action or addressbook to move to
|
||||
select migration type admin en Select migration type
|
||||
select multiple contacts for a further action addressbook en Select multiple contacts for a further action
|
||||
select phone number as prefered way of contact addressbook en select phone number as prefered way of contact
|
||||
select the type of conversion addressbook en Select the type of conversion
|
||||
@ -224,6 +232,7 @@ show a column for %1 addressbook en Show a column for %1
|
||||
show birthday reminders on main screen addressbook en Show birthday reminders on main screen
|
||||
show the contacts of this organisation addressbook en Show the contacts of this organisation
|
||||
size of popup (wxh, eg.400x300, if a popup should be used) admin en Size of popup (WxH, eg.400x300, if a popup should be used)
|
||||
start admin en Start
|
||||
startrecord addressbook en Startrecord
|
||||
state common en State
|
||||
street common en Street
|
||||
@ -244,6 +253,7 @@ update a single entry by passing the fields. addressbook en Update a single entr
|
||||
upload or delete the photo addressbook en Upload or delete the photo
|
||||
url to link telephone numbers to (use %1 for the number) admin en URL to link telephone numbers to (use %1 for the number)
|
||||
use country list addressbook en Use Country List
|
||||
use setup for a full account-migration admin en use setup for a full account-migration
|
||||
used for links and for the own sorting of the list addressbook en used for links and for the own sorting of the list
|
||||
vcard common en VCard
|
||||
vcards require a first name entry. addressbook en VCards require a first name entry.
|
||||
|
@ -59,6 +59,18 @@
|
||||
<a href="addressbook/doc/README" target="_blank">README</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td> <b>{lang_Migration_to_LDAP}</b></td>
|
||||
<td>
|
||||
<select name="migrate">
|
||||
<option value="">{lang_Select_migration_type}</option>
|
||||
<option value="contacts" title="{lang_if_accounts_are_already_in_LDAP}">{lang_contacts_to_LDAP}</option>
|
||||
<option value="contacts,accounts" title="{lang_use_setup_for_a_full_account-migration}">{lang_contacts_and_account_contact-data_to_LDAP}</option>
|
||||
<option value="contacts,accounts-back" title="{lang_for_read_only_LDAP}">{lang_contacts_to_LDAP,_account_contact-data_to_SQL}</option>
|
||||
</select>
|
||||
<input type="button" onclick="if (this.form.migrate.value) document.location.href='index.php?menuaction=addressbook.uicontacts.migrate2ldap&type='+this.form.migrate.value;" value="{lang_Start}" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- END body -->
|
||||
<!-- BEGIN footer -->
|
||||
<tr valign="bottom" style="height: 30px;">
|
||||
|
Loading…
Reference in New Issue
Block a user