mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-21 15:33:23 +01:00
* iPhone and Mac Addressbook support aka Apple CalDAV/CardDAV autodetection
Addressbook does NOT allow to specify the URL, unlike iCal which allows it after autodetection fails. This, some XML specifics set now for Apple addressbook user-agents and etags for addressbook collection itself allow now to use EGroupware with iPhone or Mac addressbook. The later was working before, if you edited the URL into a decompiled plist file, but failed now because of a new REPORT it tries on the principal, to find out shared addessbooks, which we not yet support, but failed to tell in the correct way (501 Not Implemented). Addressbook sync now the personal addressbook, because that is what we tell it as addressbook-home-set. We should add some configuration so user can choose what addressbook to set as addressbook-home-set, or to set the "all" addressbook (/addressbook). For the later we could add some prefs like SyncML to specify filters or eg. a distribution list.
This commit is contained in:
parent
73beff54fe
commit
ed733eef42
@ -458,9 +458,8 @@ class addressbook_groupdav extends groupdav_handler
|
||||
static function extra_properties(array $props=array(), $displayname, $base_uri=null)
|
||||
{
|
||||
// addressbook description
|
||||
$displayname = $GLOBALS['egw']->translation->convert(lang('Addressbook of') . ' ' .
|
||||
$displayname,
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$displayname = translation::convert(lang('Addressbook of') . ' ' .
|
||||
$displayname,translation::charset(),'utf-8');
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-description',$displayname);
|
||||
// supported reports (required property for CardDAV)
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('supported-report-set',array(
|
||||
|
28
groupdav.htaccess
Executable file
28
groupdav.htaccess
Executable file
@ -0,0 +1,28 @@
|
||||
# EGroupware CalDav or CardDAV support
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# This file can be copyied as .htaccess to your document root
|
||||
# to support Mac or iPhone clients to autodetec CalDAV and CardDAV
|
||||
# (currently Addressbook does NOT allow to specify our groupdav.php
|
||||
# URL manually).
|
||||
#
|
||||
# As alternative an EGroupware install directly in the docroot or
|
||||
# an unconditional redirect from the docroot to EGroupware's index.php
|
||||
# will archive the same thing, as it redirects PROPFIND or OPTION
|
||||
# requests to groupdav.php/ (many have such a redirect already in place).
|
||||
#
|
||||
# An other alternativ is to copy the PROPFIND/OPTION redirect from
|
||||
# the top of EGroupware's index.php into your index.php in the docroot.
|
||||
#
|
||||
# Please note:
|
||||
# - your Apache web server needs to be setup to read .htaccess files and
|
||||
# allow use of the RewriteEngine directive (AllowOverride FileInfo).
|
||||
# - you need to replace /egroupware with your EGroupware URL path eg. /egw
|
||||
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
|
||||
RewriteRule ^.well-known/(caldav|carddav)$ /egroupware/groupdav.php/ [R]
|
||||
RewriteCond %{REQUEST_METHOD} ^PROPFIND$
|
||||
RewriteRule ^/$ /egroupware/groupdav.php/
|
@ -25,8 +25,9 @@ $GLOBALS['egw_info'] = array(
|
||||
)
|
||||
);
|
||||
// if you move this file somewhere else, you need to adapt the path to the header!
|
||||
require_once('phpgwapi/inc/class.egw_digest_auth.inc.php');
|
||||
include(dirname(__FILE__).'/header.inc.php');
|
||||
$egw_dir = dirname(__FILE__);
|
||||
require_once($egw_dir.'/phpgwapi/inc/class.egw_digest_auth.inc.php');
|
||||
include($egw_dir.'/header.inc.php');
|
||||
|
||||
$GLOBALS['egw_info']['user']['preferences'] = $GLOBALS['egw']->preferences->read_repository();
|
||||
|
||||
|
@ -10,6 +10,15 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
// support of Mac or iPhone trying to autodetect CalDAV or CardDAV support
|
||||
// if EGroupware is not installed in the docroot, you need either this code in the index.php there,
|
||||
// or an uncoditional redirect to this file or copy groupdav.htaccess to your docroot as .htaccess
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND' || $_SERVER['REQUEST_METHOD'] == 'OPTIONS')
|
||||
{
|
||||
header('Location: groupdav.php/');
|
||||
exit;
|
||||
}
|
||||
|
||||
// forward for not existing or empty header to setup
|
||||
if(!file_exists('header.inc.php') || !filesize('header.inc.php'))
|
||||
{
|
||||
|
@ -550,9 +550,8 @@ class infolog_groupdav extends groupdav_handler
|
||||
static function extra_properties(array $props=array(), $displayname, $base_uri=null)
|
||||
{
|
||||
// calendar description
|
||||
$displayname = $GLOBALS['egw']->translation->convert(lang('Tasks of') . ' ' .
|
||||
$displayname,
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$displayname = translation::convert(lang('Tasks of') . ' ' .
|
||||
$displayname,translation::charset(),'utf-8');
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-description',$displayname);
|
||||
// email of the current user, see caldav-sheduling draft
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
|
||||
|
@ -97,12 +97,6 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
* @var string
|
||||
*/
|
||||
var $egw_charset;
|
||||
/**
|
||||
* Reference to the translation class
|
||||
*
|
||||
* @var translation
|
||||
*/
|
||||
var $translation;
|
||||
/**
|
||||
* Instance of our application specific handler
|
||||
*
|
||||
@ -133,6 +127,11 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
case 'kde': // KAddressbook (at least in 3.5 can NOT subscribe / does NOT find addressbook)
|
||||
$this->client_require_href_as_url = true;
|
||||
break;
|
||||
case 'cfnetwork': // Apple addressbook app
|
||||
case 'dataaccess': // iPhone addressbook
|
||||
$this->client_require_href_as_url = false;
|
||||
$this->cnrnd = true;
|
||||
break;
|
||||
case 'davkit': // iCal app in OS X 10.6 created wrong request, if full url given
|
||||
$this->client_require_href_as_url = false;
|
||||
break;
|
||||
@ -144,8 +143,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
}
|
||||
parent::HTTP_WebDAV_Server();
|
||||
|
||||
$this->translation =& $GLOBALS['egw']->translation;
|
||||
$this->egw_charset = $this->translation->charset();
|
||||
$this->egw_charset = translation::charset();
|
||||
if (strpos($this->base_uri, 'http') === 0)
|
||||
{
|
||||
$this->principalURL = $this->_slashify($this->base_uri);
|
||||
@ -156,6 +154,12 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
'//' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . '/';
|
||||
}
|
||||
$this->principalURL .= 'principals/users/'.$GLOBALS['egw_info']['user']['account_lid'].'/';
|
||||
|
||||
// if client requires pathes instead of URLs
|
||||
if ($this->client_require_href_as_url === false)
|
||||
{
|
||||
$this->principalURL = parse_url($this->principalURL,PHP_URL_PATH);
|
||||
}
|
||||
$this->accounts = $GLOBALS['egw']->accounts;
|
||||
}
|
||||
|
||||
@ -183,7 +187,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
switch($app)
|
||||
{
|
||||
case 'calendar':
|
||||
$dav[] = 2;
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'calendar-access';
|
||||
//$dav[] = 'calendar-schedule';
|
||||
@ -192,15 +196,16 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
//$dav[] = 'calendarserver-private-events';
|
||||
break;
|
||||
case 'addressbook':
|
||||
$dav[] = 2;
|
||||
$dav[] = 3;
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
//$dav[] = 3; // revision aka versioning support not implemented
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'addressbook-access';
|
||||
$dav[] = 'addressbook'; // CardDAV uses "addressbook" NOT "addressbook-access"
|
||||
break;
|
||||
default:
|
||||
$dav[] = 2;
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'calendar-access';
|
||||
$dav[] = 'addressbook';
|
||||
}
|
||||
// not yet implemented: $dav[] = 'access-control';
|
||||
}
|
||||
@ -291,7 +296,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
// OUTBOX URLs of the current user
|
||||
self::mkprop(groupdav::CALDAV,'schedule-outbox-URL',array(
|
||||
self::mkprop(groupdav::DAV,'href',$this->base_uri.'/calendar/'))),
|
||||
);
|
||||
);
|
||||
//$props = self::current_user_privilege_set($props);
|
||||
$files['files'][] = array(
|
||||
'path' => $path,
|
||||
@ -326,6 +331,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
$props[] = self::mkprop(
|
||||
groupdav::CALENDARSERVER,'getctag',$handler->getctag($options['path'],$user));
|
||||
}
|
||||
$props[] = self::mkprop('getetag','EGw-'.$app.'-wGE');
|
||||
$files['files'][] = array(
|
||||
'path' => $path.$app.'/',
|
||||
'props' => $props,
|
||||
@ -349,7 +355,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
'props' => $this->_properties($app,$app=='addressbook'&&strpos($_SERVER['HTTP_USER_AGENT'],'KHTML') !== false,$user,$path),
|
||||
);
|
||||
}
|
||||
if (isset($options['depth']) && !$options['depth'] && !$id)
|
||||
if ($method != 'REPORT' && isset($options['depth']) && !$options['depth'] && !$id)
|
||||
{
|
||||
// add ctag if handler implements it (only for depth 0)
|
||||
if (method_exists($handler,'getctag'))
|
||||
@ -412,7 +418,8 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
self::mkprop('href',$this->base_uri.'/principals/'.$principalType.'/'.$GLOBALS['egw_info']['user']['account_lid'].'/'),
|
||||
self::mkprop('href','urn:uuid:'.$GLOBALS['egw_info']['user']['account_lid']))),
|
||||
self::mkprop(groupdav::CALENDARSERVER,'email-address-set',array(
|
||||
self::mkprop(groupdav::CALENDARSERVER,'email-address',$GLOBALS['egw_info']['user']['email']))),
|
||||
self::mkprop(groupdav::CALENDARSERVER,'email-address',$GLOBALS['egw_info']['user']['email']))),
|
||||
self::mkprop('getetag','EGw-no-etag-wGE'), // iPhone addressbook requires an etag here!
|
||||
);
|
||||
|
||||
switch ($app)
|
||||
@ -427,13 +434,13 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
case 'infolog':
|
||||
$props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array(
|
||||
self::mkprop('href',$this->base_uri.$path.'infolog/')));
|
||||
$displayname = $this->translation->convert(lang($app).' '.
|
||||
$displayname = translation::convert(lang($app).' '.
|
||||
common::grab_owner_name($user),$this->egw_charset,'utf-8');
|
||||
break;
|
||||
default:
|
||||
$props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array(
|
||||
self::mkprop('href',$this->base_uri.$path)));
|
||||
$displayname = $this->translation->convert(lang($app).' '.
|
||||
$displayname = translation::convert(lang($app).' '.
|
||||
common::grab_owner_name($user),$this->egw_charset,'utf-8');
|
||||
}
|
||||
$props[] = self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
|
||||
|
@ -31,12 +31,6 @@ abstract class groupdav_handler
|
||||
* @var string
|
||||
*/
|
||||
var $egw_charset;
|
||||
/**
|
||||
* Reference to the translation class
|
||||
*
|
||||
* @var translation
|
||||
*/
|
||||
var $translation;
|
||||
/**
|
||||
* Reference to the accounts class
|
||||
*
|
||||
@ -110,8 +104,7 @@ abstract class groupdav_handler
|
||||
|
||||
$this->agent = self::get_agent();
|
||||
|
||||
$this->translation =& $GLOBALS['egw']->translation;
|
||||
$this->egw_charset = $this->translation->charset();
|
||||
$this->egw_charset = translation::charset();
|
||||
$this->accounts = $GLOBALS['egw']->accounts;
|
||||
}
|
||||
|
||||
@ -341,14 +334,15 @@ abstract class groupdav_handler
|
||||
// identify the agent (GroupDAV client) from the HTTP_USER_AGENT header
|
||||
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
foreach(array(
|
||||
'iphone' => 'iphone', // Apple iPhone iCal
|
||||
'iphone' => 'iphone', // Apple iPhone iCal
|
||||
'davkit' => 'davkit', // Apple iCal
|
||||
'cfnetwork' => 'cfnetwork', // Apple Addressbook
|
||||
'dataaccess' => 'dataaccess', // Apple addressbook iPhone
|
||||
'cfnetwork' => 'cfnetwork', // Apple Addressbook
|
||||
'bionicmessage.net' => 'funambol', // funambol GroupDAV connector from bionicmessage.net
|
||||
'zideone' => 'zideone', // zideone outlook plugin
|
||||
'lightning' => 'lightning', // Lighting (SOGo connector for addressbook)
|
||||
'khtml' => 'kde', // KDE clients
|
||||
'neon' => 'neon'
|
||||
'neon' => 'neon'
|
||||
) as $pattern => $name)
|
||||
{
|
||||
if (strpos($user_agent,$pattern) !== false)
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* eGroupWare: GroupDAV access: groupdav/caldav/carddav principals handlers
|
||||
* EGroupware: GroupDAV access: groupdav/caldav/carddav principals handlers
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* eGroupWare: GroupDAV access: groupdav/caldav/carddav principals handlers
|
||||
* EGroupware: GroupDAV access: groupdav/caldav/carddav principals handlers
|
||||
*/
|
||||
class groupdav_principals extends groupdav_handler
|
||||
{
|
||||
@ -41,6 +41,12 @@ class groupdav_principals extends groupdav_handler
|
||||
*/
|
||||
function propfind($path,$options,&$files,$user)
|
||||
{
|
||||
// we do NOT support REPORTS on pricipals yet
|
||||
// required for Apple Addressbook on Mac (addressbook-findshared REPORT)
|
||||
if ($options['root']['name'] && $options['root']['name'] != 'propfind')
|
||||
{
|
||||
return '501 Not Implemented';
|
||||
}
|
||||
list(,$principals,$type,$name,$rest) = explode('/',$path,5);
|
||||
// /principals/users/$name/
|
||||
// /users/$name/calendar-proxy-read/
|
||||
@ -82,8 +88,8 @@ class groupdav_principals extends groupdav_handler
|
||||
}
|
||||
foreach($id ? array($this->accounts->read($id)) : $this->accounts->search(array('type' => 'accounts')) as $account)
|
||||
{
|
||||
$displayname = $this->translation->convert($account['account_fullname'],
|
||||
$this->translation->charset(),'utf-8');
|
||||
$displayname = translation::convert($account['account_fullname'],
|
||||
translation::charset(),'utf-8');
|
||||
|
||||
$props = array(
|
||||
HTTP_WebDAV_Server::mkprop('displayname',$displayname),
|
||||
@ -234,8 +240,8 @@ class groupdav_principals extends groupdav_handler
|
||||
{
|
||||
//echo "<p>".__METHOD__."(".array2string($account).")</p>\n";
|
||||
|
||||
$displayname = $this->translation->convert($account['account_fullname'],
|
||||
$this->translation->charset(),'utf-8');
|
||||
$displayname = translation::convert($account['account_fullname'],
|
||||
translation::charset(),'utf-8');
|
||||
$memberships = array();
|
||||
foreach($this->accounts->memberships($account['account_id']) as $gid => $group)
|
||||
{
|
||||
@ -291,8 +297,8 @@ class groupdav_principals extends groupdav_handler
|
||||
*/
|
||||
protected function add_group(array $account)
|
||||
{
|
||||
$displayname = $this->translation->convert(lang('Group').' '.$account['account_lid'],
|
||||
$this->translation->charset(),'utf-8');
|
||||
$displayname = translation::convert(lang('Group').' '.$account['account_lid'],
|
||||
translation::charset(),'utf-8');
|
||||
$members = array();
|
||||
foreach($this->accounts->members($account['account_id']) as $gid => $user)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user