* CalDAV/CardDAV: show addressbooks/calendars selected to sync in prefs under users addressbook-/calendar-home-set (incl. account addressbook, if enabled)

This commit is contained in:
Ralf Becker 2012-01-25 03:25:42 +00:00
parent ba9c778c68
commit a679a49196
5 changed files with 231 additions and 77 deletions

View File

@ -331,7 +331,7 @@ class groupdav extends HTTP_WebDAV_Server
$this->propfind_options = $options;
// parse path in form [/account_lid]/app[/more]
if (!self::_parse_path($options['path'],$id,$app,$user,$user_prefix) && $app && !$user)
if (!self::_parse_path($options['path'],$id,$app,$user,$user_prefix) && $app && !$user && $user !== 0)
{
if ($this->debug > 1) error_log(__CLASS__."::$method: user='$user', app='$app', id='$id': 404 not found!");
return '404 Not Found';
@ -354,9 +354,9 @@ class groupdav extends HTTP_WebDAV_Server
'displayname' => lang('Accounts'),
));
// todo: account_selection owngroups and none!!!
foreach($this->accounts->search(array('type' => 'both')) as $account)
foreach($this->accounts->search(array('type' => 'both','order'=>'account_lid')) as $account)
{
$this->add_home($files, $path.$account['account_lid'].'/', $user, $options['depth'] == 'infinity' ? 'infinity' : $options['depth']-1);
$this->add_home($files, $path.$account['account_lid'].'/', $account['account_id'], $options['depth'] == 'infinity' ? 'infinity' : $options['depth']-1);
}
}
return true;
@ -371,7 +371,7 @@ class groupdav extends HTTP_WebDAV_Server
if ($method != 'REPORT' && !$id) // no self URL for REPORT requests (only PROPFIND) or propfinds on an id
{
// KAddressbook doubles the folder, if the self URL contains the GroupDAV/CalDAV resourcetypes
$files['files'][0] = $this->add_app($app,$app=='addressbook'&&$handler->get_agent()=='kde',$user,$path);
$files['files'][0] = $this->add_app($app,$app=='addressbook'&&$handler->get_agent()=='kde',$user,$path.$app.'/');
// Hack for iOS 5.0.1 addressbook to stop asking directory gateway permissions with depth=1
if ($method == 'PROPFIND' && $options['path'] == '/addressbook/' && $handler->get_agent() == 'dataaccess')
@ -590,12 +590,126 @@ class groupdav extends HTTP_WebDAV_Server
if (!$GLOBALS['egw_info']['user']['apps'][$data['app'] ? $data['app'] : $app]) continue; // no rights for the given app
if (!empty($data['user-only']) && ($path == '/' || $user < 0)) continue;
$files['files'][] = $this->add_app($app,false,$user,$path);
$files['files'][] = $this->add_app($app,false,$user,$path.$app.'/');
// added shared calendars or addressbooks
$this->add_shared($files['files'], $path, $app, $user);
}
}
return true;
}
/**
* Add shared addressbook, calendar, infolog to user home
*
* @param array &$files
* @param string $path /<username>/
* @param int $app
* @param int $user
* @return string|boolean http status or true|false
*/
protected function add_shared(array &$files, $path, $app, $user)
{
// currently only show shared calendars/addressbooks for current user and not in the root
if ($path == '/' || $user != $GLOBALS['egw_info']['user']['account_id'])
{
return true;
}
switch($app)
{
case 'addressbook':
$addressbook_home_set = $GLOBALS['egw_info']['user']['preferences']['groupdav']['addressbook-home-set'];
if (empty($addressbook_home_set)) $addressbook_home_set = 'P'; // personal addressbook
$addressbook_home_set = explode(',',$addressbook_home_set);
// replace symbolic id's with real nummeric id's
foreach(array(
'G' => $GLOBALS['egw_info']['user']['account_primary_group'],
'U' => '0',
) as $sym => $id)
{
if (($key = array_search($sym, $addressbook_home_set)) !== false)
{
$addressbook_home_set[$key] = $id;
}
}
foreach(ExecMethod('addressbook.addressbook_bo.get_addressbooks',EGW_ACL_READ) as $id => $label)
{
if (($id || !$GLOBALS['egw_info']['user']['preferences']['addressbook']['hide_accounts']) &&
$user != $id && // no current user and no accounts, if disabled in ab prefs
(in_array('A',$addressbook_home_set) || in_array((string)$id,$addressbook_home_set)) &&
is_numeric($id) && ($owner = $id ? $this->accounts->id2name($id) : 'accounts'))
{
$files[] = $this->add_app($app,false,$id,$path.'addressbook-'.$owner.'/');
}
}
break;
case 'calendar':
$calendar_home_set = $GLOBALS['egw_info']['user']['preferences']['groupdav']['calendar-home-set'];
$calendar_home_set = $calendar_home_set ? explode(',',$calendar_home_set) : array();
// replace symbolic id's with real nummeric id's
foreach(array(
'G' => $GLOBALS['egw_info']['user']['account_primary_group'],
) as $sym => $id)
{
if (($key = array_search($sym, $calendar_home_set)) !== false)
{
$calendar_home_set[$key] = $id;
}
}
foreach(ExecMethod('calendar.calendar_bo.list_cals') as $entry)
{
$id = $entry['grantor'];
if ($id && $user != $id && // no current user and no accounts yet (todo)
(in_array('A',$calendar_home_set) || in_array((string)$id,$calendar_home_set)) &&
is_numeric($id) && ($owner = $this->accounts->id2name($id)))
{
$files[] = $this->add_app($app,false,$id,$path.'calendar-'.$owner.'/');
}
}
break;
case 'infolog':
// ToDo:
break;
}
return true;
}
/**
* Format an account-name for use in displayname
*
* @param int|array $account
* @return string
*/
public function account_name($account)
{
if (is_array($account))
{
if ($account['account_id'] < 0)
{
$name = lang('Group').' '.$account['account_lid'];
}
else
{
$name = $account['account_fullname'];
}
}
else
{
if ($account < 0)
{
$name = lang('Group').' '.$this->accounts->id2name($account,'account_lid');
}
else
{
$name = $this->accounts->id2name($account,'account_fullname');
}
if (empty($name)) $name = '#'.$account;
}
return $name;
}
/**
* Add an application collection to a user home or the root
*
@ -625,7 +739,6 @@ class groupdav extends HTTP_WebDAV_Server
}
$account = $this->accounts->read($account_lid);
$displayname = translation::convert($account['account_fullname'],translation::charset(),'utf-8');
if ($user < 0)
{
@ -643,13 +756,26 @@ class groupdav extends HTTP_WebDAV_Server
switch ($app)
{
case 'inbox':
$props['displayname'] = lang('Scheduling inbox').' '.common::grab_owner_name($user);
$props['displayname'] = lang('Scheduling inbox').' '.$this->account_name($user);
break;
case 'outbox':
$props['displayname'] = lang('Scheduling outbox').' '.common::grab_owner_name($user);
$props['displayname'] = lang('Scheduling outbox').' '.$this->account_name($user);
break;
case 'addressbook':
if ($path == '/addressbook/')
{
$props['displayname'] = lang('All addressbooks');
break;
}
elseif(!$user && !$GLOBALS['egw_info']['user']['preferences']['addressbook']['hide_accounts'])
{
unset($props['owner']);
$props['displayname'] = lang($app).' '.lang('Accounts');
break;
}
// fall through
default:
$props['displayname'] = translation::convert(lang($app).' '.common::grab_owner_name($user),$this->egw_charset,'utf-8');
$props['displayname'] = translation::convert(lang($app).' '.$this->account_name($user),$this->egw_charset,'utf-8');
}
// add props modifyable via proppatch from client, eg. calendar-color, see self::$proppatch_props
@ -703,10 +829,7 @@ class groupdav extends HTTP_WebDAV_Server
{
if (method_exists($handler,'extra_properties'))
{
$displayname = translation::convert(
$account['account_id'] > 0 ? $account['account_fullname'] : lang('Group').' '.$account['account_lid'],
translation::charset(),'utf-8');
$props = $handler->extra_properties($props,$displayname,$this->base_uri,$user);
$props = $handler->extra_properties($props,$this->account_name($account),$this->base_uri,$user);
}
// add ctag if handler implements it
if (method_exists($handler,'getctag') && $this->prop_requested('getctag') === true)
@ -715,9 +838,11 @@ class groupdav extends HTTP_WebDAV_Server
groupdav::CALENDARSERVER,'getctag',$handler->getctag($path,$user));
}
}
if ($handler) $privileges = $handler->current_user_privileges($path.$app.'/', $user) ;
return $this->add_collection($path.$app.'/', $props, $privileges);
if ($handler && $user)
{
return $this->add_collection($path, $props, $handler->current_user_privileges($path, $user));
}
return $this->add_collection($path, $props);
}
/**
@ -803,6 +928,16 @@ class groupdav extends HTTP_WebDAV_Server
}
echo "</h1>\n";
static $props2show = array(
'DAV:getcontentlength' => 'Size',
'DAV:getlastmodified' => 'Last modified',
'DAV:getetag' => 'ETag',
'DAV:getcontenttype' => 'Content type',
'DAV:resourcetype' => 'Resource type',
'DAV:displayname' => 'Displayname',
//'DAV:owner' => 'Owner',
//'DAV:current-user-privilege-set' => 'current-user-privilege-set',
);
$n = 0;
foreach($files['files'] as $file)
{
@ -814,8 +949,9 @@ class groupdav extends HTTP_WebDAV_Server
}
if(!$n++)
{
echo "<table>\n\t<tr class='th'><th>#</th><th>".lang('Name')."</th><th>".lang('Size')."</th><th>".lang('Last modified')."</th><th>".
lang('ETag')."</th><th>".lang('Content type')."</th><th>".lang('Resource type')."</th></tr>\n";
echo "<table>\n\t<tr class='th'>\n\t\t<th>#</th>\n\t\t<th>".lang('Name')."</th>";
foreach($props2show as $label) echo "\t\t<th>".lang($label)."</th>\n";
echo "\t</tr>\n";
}
$props = $this->props2array($file['props']);
//echo $file['path']; _debug_array($props);
@ -836,11 +972,11 @@ class groupdav extends HTTP_WebDAV_Server
'#' => '%23',
'?' => '%3F',
)))."</td>\n";
echo "\t\t<td>".$props['DAV:getcontentlength']."</td>\n";
echo "\t\t<td>".(!empty($props['DAV:getlastmodified']) ? date('Y-m-d H:i:s',$props['DAV:getlastmodified']) : '')."</td>\n";
echo "\t\t<td>".$props['DAV:getetag']."</td>\n";
echo "\t\t<td>".$props['DAV:getcontenttype']."</td>\n";
echo "\t\t<td>".$props['DAV:resourcetype']."</td>\n\t</tr>\n";
foreach($props2show as $prop => $label)
{
echo "\t\t<td>".($prop=='DAV:getlastmodified'&&!empty($props[$prop])?date('Y-m-d H:i:s',$props[$prop]):$props[$prop])."</td>\n";
}
echo "\t</tr>\n";
}
if (!$n)
{
@ -903,7 +1039,7 @@ class groupdav extends HTTP_WebDAV_Server
}
if (preg_match('/\<(D:)?href\>[^<]+\<\/(D:)?href\>/i',$value))
{
$value = '<pre>'.preg_replace('/\<(D:)?href\>([^<]+)\<\/(D:)?href\>/i','&lt;\\1href&gt;<a href="\\2">\\2</a>&lt;/\\3href&gt;',$value).'</pre>';
$value = '<pre>'.preg_replace('/\<(D:)?href\>('.preg_quote($this->base_uri.'/','/').')?([^<]+)\<\/(D:)?href\>/i','&lt;\\1href&gt;<a href="\\2\\3">\\3</a>&lt;/\\4href&gt;',$value).'</pre>';
}
else
{
@ -1255,7 +1391,23 @@ class groupdav extends HTTP_WebDAV_Server
$app = array_shift($parts);
if ($user)
// shared calendars/addressbooks at /<currentuser>/(calendar|addressbook|infolog)-<username>
if ($account_id == $GLOBALS['egw_info']['user']['account_id'] && strpos($app, '-') !== false)
{
list($app, $username) = explode('-', $app, 2);
if ($username == 'accounts')
{
$account_id = 0;
}
elseif (!($account_id = $this->accounts->name2id($username, 'account_lid')) &&
!($account_id = $this->accounts->name2id($username=urldecode($username))))
{
return false;
}
$user = $account_id;
$user_prefix = '/'.$GLOBALS['egw_info']['user']['account_lid'].'/'.$app.'-'.$username;
}
elseif ($user)
{
$user_prefix = '/'.$user;
$user = $account_id;
@ -1268,7 +1420,7 @@ class groupdav extends HTTP_WebDAV_Server
$id = array_pop($parts);
$ok = $id && $user && in_array($app,array('addressbook','calendar','infolog','principals'));
$ok = $id && ($user || $user === 0) && in_array($app,array('addressbook','calendar','infolog','principals'));
if ($this->debug)
{
error_log(__METHOD__."('$path') returning " . ($ok ? 'true' : 'false') . ": id='$id', app='$app', user='$user', user_prefix='$user_prefix'");

View File

@ -61,15 +61,13 @@ class groupdav_hooks
$user = $GLOBALS['egw_info']['user']['account_id'];
$addressbook_bo = new addressbook_bo();
$addressbooks = $addressbook_bo->get_addressbooks(EGW_ACL_READ);
unset($addressbooks[$user]); // Use P for personal addressbook
unset($addressbooks[$user]); // allways synced
unset($addressbooks[$user.'p']);// ignore (optional) private addressbook for now
}
$addressbooks = array(
'P' => lang('Personal'),
'G' => lang('Primary Group'),
//'U' => lang('Accounts'), // not yet working
'O' => lang('All in one'),
'A' => lang('All'),
'G' => lang('Primary Group'),
'U' => lang('Accounts'),
) + $addressbooks;
// rewriting owner=0 to 'U', as 0 get's always selected by prefs
@ -84,13 +82,41 @@ class groupdav_hooks
$settings['addressbook-home-set'] = array(
'type' => 'multiselect',
'label' => 'Addressbooks to sync with Apple clients',
'label' => 'Addressbooks to sync in addition to personal addressbook',
'name' => 'addressbook-home-set',
'help' => 'Addressbooks for CardDAV attribute "addressbook-home-set".',
'help' => lang('Only supported by a few fully conformant clients (eg. from Apple). If you have to enter a URL, it will most likly not be suppored!').'<br/>'.lang('They will be sub-folders in users home (%1 attribute).','CardDAV "addressbook-home-set"'),
'values' => $addressbooks,
'xmlrpc' => True,
'admin' => False,
'default' => 'P',
);
if ($hook_data['setup'])
{
$calendars = array();
}
else
{
$user = $GLOBALS['egw_info']['user']['account_id'];
$cal_bo = new calendar_bo();
foreach ($cal_bo->list_cals() as $entry)
{
$calendars[$entry['grantor']] = $entry['name'];
}
unset($calendars[$user]);
}
$calendars = array(
'A' => lang('All'),
'G' => lang('Primary Group'),
) + $calendars;
$settings['calendar-home-set'] = array(
'type' => 'multiselect',
'label' => 'Calendars to sync in addition to personal calendar',
'name' => 'calendar-home-set',
'help' => lang('Only supported by a few fully conformant clients (eg. from Apple). If you have to enter a URL, it will most likly not be suppored!').'<br/>'.lang('They will be sub-folders in users home (%1 attribute).','CalDAV "calendar-home-set"'),
'values' => $calendars,
'xmlrpc' => True,
'admin' => False,
);
translation::add_app('infolog');

View File

@ -600,7 +600,7 @@ class groupdav_principals extends groupdav_handler
else
{
// add all users (account_selection == groupmembers is handled by accounts->search())
foreach($this->accounts->search(array('type' => 'accounts')) as $account)
foreach($this->accounts->search(array('type' => 'accounts','order' => 'account_lid')) as $account)
{
$files[] = $this->add_account($account);
}
@ -669,7 +669,7 @@ class groupdav_principals extends groupdav_handler
'owngroups' : 'groups';
// add all groups or only membergroups
foreach($this->accounts->search(array('type' => $type)) as $account)
foreach($this->accounts->search(array('type' => $type,'order' => 'account_lid')) as $account)
{
$files[] = $this->add_group($account);
}
@ -755,34 +755,12 @@ class groupdav_principals extends groupdav_handler
protected function add_account(array $account)
{
$addressbooks = $calendars = array();
if ($account['account_id'] == $GLOBALS['egw_info']['user']['account_id'])
{
foreach($this->get_shared_addressbooks() as $path)
{
$addressbooks[] = HTTP_WebDAV_Server::mkprop('href',$this->base_uri.$path);
}
// since we "show" shared addressbooks and calendars in the user home, no need for individualiced homes
$addressbooks[] = HTTP_WebDAV_Server::mkprop('href',
$this->base_uri.'/'.$account['account_lid'].'/');
$calendars[] = HTTP_WebDAV_Server::mkprop('href',
$this->base_uri.'/'.$account['account_lid'].'/');
$calendars[] = HTTP_WebDAV_Server::mkprop('href',
$this->base_uri.'/'.$account['account_lid'].'/');
/* iCal send propfind to wrong url (concatinated href's), if we return multiple href in calendar-home-set
$cal_bo = new calendar_bo();
foreach ($cal_bo->list_cals() as $label => $entry)
{
$id = $entry['grantor'];
$owner = $this->accounts->id2name($id);
$calendars[] = HTTP_WebDAV_Server::mkprop('href',
$this->base_uri.'/'.$owner.'/');
}
*/
}
else
{
$addressbooks[] = HTTP_WebDAV_Server::mkprop('href',
$this->base_uri.'/'.$account['account_lid'].'/');
$calendars[] = HTTP_WebDAV_Server::mkprop('href',
$this->base_uri.'/'.$account['account_lid'].'/');
}
$displayname = translation::convert($account['account_fullname'], translation::charset(),'utf-8');
return $this->add_principal('users/'.$account['account_lid'], array(

View File

@ -41,19 +41,18 @@ add category common de Kategorie hinzufügen
add shortcut common de Abkürzung hinzufügen
add sub common de Untergeordnete hinzufügen
addressbook common de Adressbuch
addressbooks for carddav attribute "addressbook-home-set". common de Adressbücher für CardDAV Attribut "addressbook-home-set".
addressbooks to sync with apple clients common de Adressbücher zum Synchronisieren mit Apple Programmen
addressbooks to sync in addition to personal addressbook groupdav de Adressbücher die zusätzlich zum persönlichen synchronisiert werden sollen
admin common de Admin
administration common de Administration
afghanistan common de AFGHANISTAN
albania common de ALBANIEN
algeria common de ALGERIEN
all common de alle
all addressbooks groupdav de Alle Adressbücher
all fields common de alle Felder
all in one common de Gemeinsam in einem
all in one groupdav de Gemeinsam in einem
all languages common de Alle Sprachen
alphabet common de a,ä,b,c,d,e,f,g,h,i,j,k,l,m,n,o,ö,p,q,r,s,t,u,ü,v,w,x,y,z
alt common de Alt
alternate style-sheet: common de Alternatives Style-sheet
american samoa common de AMERICANISCH SAMOA
an admin required that you must change your password upon login. common de Sie werden hiermit aufgefordert Ihr Passwort zu ändern. (Dies wurde von einem Administrator veranlasst.)
@ -116,6 +115,7 @@ bulgarian common de Bulgarisch
burkina faso common de BURKINA FASO
burundi common de BURUNDI
calendar common de Kalender
calendars to sync in addition to personal calendar groupdav de Kalender die zusätzlich zum persönlichen synchronisiert werden sollen.
cambodia common de KAMBODSCHA
cameroon common de KAMERUN
canada common de KANADA
@ -180,7 +180,6 @@ could not contact server. operation timed out! common de Konnte Server nicht kon
create common de Erstellen
created by common de Erstellt von
croatia common de KROATIEN
ctrl common de Strg
cuba common de KUBA
currency common de Währung
current common de derzeit
@ -198,7 +197,6 @@ december common de Dezember
default category common de Standard-Kategorie
default height for the windows common de Vorgabewert für Höhe des Fensters
default width for the windows common de Vorgabewert für Breite des Fensters
del common de Entf
delete common de Löschen
delete category common de Kategorie entfernen
delete row common de Zeile löschen
@ -503,6 +501,7 @@ oman common de OMAN
on *nix systems please type: %1 common de Auf *nix systemen bitte %1 eingeben
on mouse over common de On Maus Over
only private common de nur private
only supported by a few fully conformant clients (eg. from apple). if you have to enter a url, it will most likly not be suppored! groupdav de Wird nur von einigen vollständigen Clients (z.B. von Apple) unterstützt. Wenn Sie eine URL eingeben müssen, wird es vermutlich nicht unterstützt!
only yours common de nur eigene
oops! you caught us in the middle of system maintainance. common de Hoppla! Sie haben uns in der Mitte einer Systemwartung erwischt.
open common de Öffnen
@ -539,8 +538,6 @@ permissions to the files/users directory common de Zugriffsrechte zu den Dateien
permisson denied! common de Zugriff verweigert!
personal common de persönlich
peru common de PERU
pg down common de Bild ab
pg up common de Bild auf
philippines common de PHILIPPINEN
phone number common de Telefonnummer
phpgwapi common de EGroupware API
@ -640,7 +637,6 @@ session has been killed common de Session wurde beendet
setup common de Setup
setup main menu common de Setup Hauptmenü
seychelles common de SEYCHELLEN
shift common de Umsch
show all common de alle anzeigen
show all categorys common de Alle Kategorien anzeigen
show as topmenu common de Menü oben anzeigen
@ -668,7 +664,6 @@ somalia common de SOMALIA
sorry, your login has expired login de Ihre Anmeldung ist abgelaufen !
south africa common de SÜDAFRIKA
south georgia and the south sandwich islands common de SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
space common de Leer
spain common de SPANIEN
sri lanka common de SRI LANKA
start date common de Startdatum
@ -689,7 +684,6 @@ swaziland common de SWAZILAND
sweden common de SCHWEDEN
switzerland common de SCHWEIZ
syrian arab republic common de SYRIEN, ARABISCHE REPUBLIK
tab common de Tab
table %1 is excluded from backup and restore. data will not be restored. common de Tabelle %1 ist ausgeschlossen von der Datensicherung und der Wiederherstellung. Die Daten werden nicht wiederhergestellt.
table properties common de Tabelleneigenschaften
taiwan common de TAIWAN/TAIPEI
@ -702,6 +696,7 @@ the api requires an upgrade common de Die API benötigt eine Aktualisierung
the following applications require upgrades common de Die folgenden Anwendungen benötigen eine Aktualisierung
the mail server returned common de Der E-Mail-Server liefert zurück
there already is a system-user with this name. user's should not have the same name as a systemuser common de Es gibt schon einen system Benutzer mit dem selben Namen. Die Benutzer sollten nicht die gleichen Namen haben, wie die Systembenutzer.
they will be sub-folders in users home (%1 attribute). common de Diese werden Unterordner im Homeverzeichnis des Benutzers (%1 Attribute).
this application is current common de Diese Anwendung ist aktuell
this application requires an upgrade common de Diese Anwendung benötigt eine Aktualisierung
this name has been used already common de Dieser Name ist bereits in Benutzung !

View File

@ -41,16 +41,16 @@ add category common en Add category
add shortcut common en Add shortcut
add sub common en Add sub
addressbook common en Address Book
addressbooks for carddav attribute "addressbook-home-set". common en Address books for CardDAV attribute "addressbook-home-set".
addressbooks to sync with apple clients common en Address books to sync with Apple clients
addressbooks to sync in addition to personal addressbook groupdav en Addressbooks to sync in addition to personal addressbook
admin common en Admin
administration common en Administration
afghanistan common en AFGHANISTAN
albania common en ALBANIA
algeria common en ALGERIA
all common en All
all addressbooks groupdav en All addressbooks
all fields common en All fields
all in one common en All in one
all in one groupdav en All in one
all languages common en All languages
alphabet common en a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
alternate style-sheet: common en Alternate style sheet:
@ -115,6 +115,7 @@ bulgarian common en Bulgarian
burkina faso common en BURKINA FASO
burundi common en BURUNDI
calendar common en Calendar
calendars to sync in addition to personal calendar groupdav en Calendars to sync in addition to personal calendar
cambodia common en CAMBODIA
cameroon common en CAMEROON
canada common en CANADA
@ -501,6 +502,7 @@ oman common en OMAN
on *nix systems please type: %1 common en On *nix systems please type: %1
on mouse over common en On mouse over
only private common en Only private
only supported by a few fully conformant clients (eg. from apple). if you have to enter a url, it will most likly not be suppored! groupdav en Only supported by a few fully conformant clients (eg. from Apple). If you have to enter a URL, it will most likly not be suppored!
only yours common en Only yours
oops! you caught us in the middle of system maintainance. common en Oops! You caught us in the middle of system maintenance.
open common en Open
@ -695,6 +697,7 @@ the api requires an upgrade common en The API requires an upgrade
the following applications require upgrades common en The following applications require upgrades
the mail server returned common en The mail server returned
there already is a system-user with this name. user's should not have the same name as a systemuser common en There already is a system user with this name. Please, select another name.
they will be sub-folders in users home (%1 attribute). common en They will be sub-folders in users home (%1 attribute).
this application is current common en This application is current
this application requires an upgrade common en This application requires an upgrade.
this name has been used already common en This name has been used already!