* CalDAV/Calendar/Resources: calendars of resources can now be accessed or subscribed via CalDAV, to subscribe use CalDAV preferences

This commit is contained in:
Ralf Becker 2012-09-27 15:46:08 +00:00
parent 9c8f7fe1ea
commit db4bdb7f74
8 changed files with 231 additions and 51 deletions

View File

@ -967,7 +967,7 @@ class addressbook_groupdav extends groupdav_handler
(in_array('A',$this->home_set_pref) || in_array((string)$id,$this->home_set_pref)) && (in_array('A',$this->home_set_pref) || in_array((string)$id,$this->home_set_pref)) &&
is_numeric($id) && ($owner = $id ? $this->accounts->id2name($id) : 'accounts')) is_numeric($id) && ($owner = $id ? $this->accounts->id2name($id) : 'accounts'))
{ {
$shared[$id] = $owner; $shared[$id] = 'addressbook-'.$owner;
} }
} }
return $shared; return $shared;

View File

@ -1970,7 +1970,7 @@ class calendar_bo
/** /**
* Query ctag for calendar * Query ctag for calendar
* *
* @param int|array $user integer user-id or array of user-id's to use, defaults to the current user * @param int|string|array $user integer user-id or array of user-id's to use, defaults to the current user
* @param string $filter='owner' all (not rejected), accepted, unknown, tentative, rejected or hideprivate * @param string $filter='owner' all (not rejected), accepted, unknown, tentative, rejected or hideprivate
* @param boolean $master_only=false only check recurance master (egw_cal_user.recur_date=0) * @param boolean $master_only=false only check recurance master (egw_cal_user.recur_date=0)
* @return integer * @return integer

View File

@ -1366,7 +1366,22 @@ class calendar_groupdav extends groupdav_handler
(in_array('A',$calendar_home_set) || in_array((string)$id,$calendar_home_set)) && (in_array('A',$calendar_home_set) || in_array((string)$id,$calendar_home_set)) &&
is_numeric($id) && ($owner = $this->accounts->id2name($id))) is_numeric($id) && ($owner = $this->accounts->id2name($id)))
{ {
$shared[$id] = $owner; $shared[$id] = 'calendar-'.$owner;
}
}
// shared locations and resources
if ($GLOBALS['egw_info']['user']['apps']['resources'])
{
foreach(array('locations','resources') as $res)
{
if (($pref = $GLOBALS['egw_info']['user']['preferences']['groupdav']['calendar-home-set-'.$res]))
{
foreach(explode(',', $pref) as $res_id)
{
$is_location = $res == 'locations';
$shared['r'.$res_id] = str_replace('s/', '-', groupdav_principals::resource2name($res_id, $is_location));
}
}
} }
} }
return $shared; return $shared;
@ -1406,6 +1421,43 @@ class calendar_groupdav extends groupdav_handler
'xmlrpc' => True, 'xmlrpc' => True,
'admin' => False, 'admin' => False,
); );
// allow to subscribe to resources
if ($GLOBALS['egw_info']['user']['apps']['resources'] && ($all_resources = groupdav_principals::get_resources()))
{
$resources = $locations = array();
foreach($all_resources as $resource)
{
if (groupdav_principals::resource_is_location($resource))
{
$locations[$resource['res_id']] = $resource['name'];
}
else
{
$resources[$resource['res_id']] = $resource['name'];
}
}
foreach(array(
'locations' => $locations,
'resources' => $resources,
) as $name => $options)
{
if ($options)
{
natcasesort($options);
$settings['calendar-home-set-'.$name] = array(
'type' => 'multiselect',
'label' => lang('%1 to sync', lang($name == 'locations' ? 'Location calendars' : 'Resource calendars')),
'no_lang'=> true,
'name' => 'calendar-home-set-'.$name,
'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' => $options,
'xmlrpc' => True,
'admin' => False,
);
}
}
}
return $settings; return $settings;
} }
} }

View File

@ -284,7 +284,7 @@ class calendar_so
* *
* This includes ALL recurences of an event series * This includes ALL recurences of an event series
* *
* @param int|array $users one or mulitple calendar users * @param int|string|array $users one or mulitple calendar users
* @param booelan $owner_too=false if true return also events owned by given users * @param booelan $owner_too=false if true return also events owned by given users
* @param boolean $master_only=false only check recurance master (egw_cal_user.recur_date=0) * @param boolean $master_only=false only check recurance master (egw_cal_user.recur_date=0)
* @return int maximum modification timestamp * @return int maximum modification timestamp
@ -295,27 +295,44 @@ class calendar_so
$signature = serialize(func_get_args()); $signature = serialize(func_get_args());
if (isset($ctags[$signature])) return $ctags[$signature]; if (isset($ctags[$signature])) return $ctags[$signature];
$types = array();
foreach((array)$users as $uid)
{
self::split_user($uid, $type, $id);
$types[$type][] = $id;
}
foreach($types as $type => $ids)
{
$where = array( $where = array(
'cal_user_type' => 'u', 'cal_user_type' => $type,
'cal_user_id' => $users, 'cal_user_id' => $ids,
); );
if (count($types) > 1)
{
$types[$type] = $this->db->expression($this->user_table, $where);
}
}
if (count($types) > 1)
{
$where[] = '('.explode(' OR ', $types).')';
}
if ($master_only) if ($master_only)
{ {
$where['cal_recur_date'] = 0; $where['cal_recur_date'] = 0;
} }
if ($owner_too) if ($owner_too)
{ {
// owner can only by users, no groups // owner can only by users, no groups or resources
foreach($users as $key => $user) foreach($users as $key => $user)
{ {
if ($user < 0) unset($users[$key]); if (!($user > 0)) unset($users[$key]);
} }
$where = $this->db->expression($this->user_table, '(', $where, ' OR '). $where = $this->db->expression($this->user_table, '(', $where, ' OR ').
$this->db->expression($this->cal_table, array( $this->db->expression($this->cal_table, array(
'cal_owner' => $users, 'cal_owner' => $users,
),')'); ),')');
} }
return $ctags[$signature] = $this->db->select($this->user_table,'MAX(cal_modified) AS max_modified', return $ctags[$signature] = $this->db->select($this->user_table,'MAX(cal_modified)',
$where,__LINE__,__FILE__,false,'','calendar',0,'JOIN egw_cal ON egw_cal.cal_id=egw_cal_user.cal_id')->fetchColumn(); $where,__LINE__,__FILE__,false,'','calendar',0,'JOIN egw_cal ON egw_cal.cal_id=egw_cal_user.cal_id')->fetchColumn();
} }

View File

@ -26,10 +26,10 @@ require_once('HTTP/WebDAV/Server.php');
* - /principals/groups/<groupname>/ * - /principals/groups/<groupname>/
* - /<username>/ users home-set with * - /<username>/ users home-set with
* - /<username>/addressbook/ addressbook of user or group <username> given the user has rights to view it * - /<username>/addressbook/ addressbook of user or group <username> given the user has rights to view it
* - /<username>/addressbook-<other-username>/ shared addressbooks from other user or group * - /<current-username>/addressbook-<other-username>/ shared addressbooks from other user or group
* - /<username>/addressbook-accounts/ all accounts current user has rights to see * - /<current-username>/addressbook-accounts/ all accounts current user has rights to see
* - /<username>/calendar/ calendar of user <username> given the user has rights to view it * - /<username>/calendar/ calendar of user <username> given the user has rights to view it
* - /<username>/calendar-<other-username>/ shared calendar from other user or group * - /<current-username>/calendar-<other-username>/ shared calendar from other user or group (only current <username>!)
* - /<username>/inbox/ scheduling inbox of user <username> * - /<username>/inbox/ scheduling inbox of user <username>
* - /<username>/outbox/ scheduling outbox of user <username> * - /<username>/outbox/ scheduling outbox of user <username>
* - /<username>/infolog/ InfoLog's of user <username> given the user has rights to view it * - /<username>/infolog/ InfoLog's of user <username> given the user has rights to view it
@ -37,6 +37,10 @@ require_once('HTTP/WebDAV/Server.php');
* - /addressbook-accounts/ all accounts current user has rights to see * - /addressbook-accounts/ all accounts current user has rights to see
* - /calendar/ calendar of current user * - /calendar/ calendar of current user
* - /infolog/ infologs of current user * - /infolog/ infologs of current user
* - /(resources|locations)/<resource-name>/calendar calendar of a resource/location, if user has rights to view
* - /<current-username>/(resource|location)-<resource-name> shared calendar from a resource/location
*
* Shared addressbooks or calendars are only shown in in users home-set, if he subscribed to it via his CalDAV preferences!
* *
* Calling one of the above collections with a GET request / regular browser generates an automatic index * Calling one of the above collections with a GET request / regular browser generates an automatic index
* from the data of a allprop PROPFIND, allow to browse CalDAV/CardDAV/GroupDAV tree with a regular browser. * from the data of a allprop PROPFIND, allow to browse CalDAV/CardDAV/GroupDAV tree with a regular browser.
@ -347,7 +351,7 @@ class groupdav extends HTTP_WebDAV_Server
if ($this->debug > 1) error_log(__CLASS__."::$method: user='$user', app='$app', id='$id': 404 not found!"); if ($this->debug > 1) error_log(__CLASS__."::$method: user='$user', app='$app', id='$id': 404 not found!");
return '404 Not Found'; return '404 Not Found';
} }
if ($this->debug > 1) error_log(__CLASS__."::$method: user='$user', app='$app', id='$id'"); if ($this->debug > 1) error_log(__CLASS__."::$method(path='$options[path]'): user='$user', user_prefix='$user_prefix', app='$app', id='$id'");
$files = array('files' => array()); $files = array('files' => array());
$path = $user_prefix = $this->_slashify($user_prefix); $path = $user_prefix = $this->_slashify($user_prefix);
@ -364,7 +368,6 @@ class groupdav extends HTTP_WebDAV_Server
$files['files'][] = $this->add_collection('/principals/', array( $files['files'][] = $this->add_collection('/principals/', array(
'displayname' => lang('Accounts'), 'displayname' => lang('Accounts'),
)); ));
// todo: account_selection owngroups and none!!!
foreach($this->accounts->search(array('type' => 'both','order'=>'account_lid')) as $account) foreach($this->accounts->search(array('type' => 'both','order'=>'account_lid')) as $account)
{ {
$this->add_home($files, $path.$account['account_lid'].'/', $account['account_id'], $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);
@ -372,6 +375,10 @@ class groupdav extends HTTP_WebDAV_Server
} }
return true; return true;
} }
if ($path == '/' && ($app == 'resources' || $app == 'locations'))
{
return $this->add_resources_collection($files, '/'.$app.'/', $options['depth']);
}
if ($app != 'principals' && !isset($GLOBALS['egw_info']['user']['apps'][$this->root[$app]['app'] ? $this->root[$app]['app'] : $app])) if ($app != 'principals' && !isset($GLOBALS['egw_info']['user']['apps'][$this->root[$app]['app'] ? $this->root[$app]['app'] : $app]))
{ {
if ($this->debug) error_log(__CLASS__."::$method(path=$options[path]) 403 Forbidden: no app rights for '$app'"); if ($this->debug) error_log(__CLASS__."::$method(path=$options[path]) 403 Forbidden: no app rights for '$app'");
@ -639,6 +646,49 @@ class groupdav extends HTTP_WebDAV_Server
// added shared calendars or addressbooks // added shared calendars or addressbooks
$this->add_shared($files['files'], $path, $app, $user); $this->add_shared($files['files'], $path, $app, $user);
} }
if ($path == '/' && $GLOBALS['egw_info']['user']['apps']['resources'])
{
$this->add_resources_collection($files, $path.'resources/');
$this->add_resources_collection($files, $path.'locations/');
}
}
return true;
}
/**
* Add collection with available resources or locations calendar-home-sets
*
* @param array &$files
* @param string $path / or /<username>/
* @param int $depth=0
* @return string|boolean http status or true|false
*/
protected function add_resources_collection(array &$files, $path, $depth=0)
{
if (!isset($GLOBALS['egw_info']['user']['apps']['resources']))
{
if ($this->debug) error_log(__CLASS__."::$method(path=$path) 403 Forbidden: no app rights for 'resources'");
return "403 Forbidden: no app rights for 'resources'"; // no rights for the given app
}
list(,$what) = explode('/', $path);
if (($is_location = ($what == 'locations')))
{
$files['files'][] = $this->add_collection('/locations/', array('displayname' => lang('Location calendars')));
}
else
{
$files['files'][] = $this->add_collection('/resources/', array('displayname' => lang('Resource calendars')));
}
if ($depth)
{
foreach(groupdav_principals::get_resources() as $res_id => $resource)
{
if ($is_location == groupdav_principals::resource_is_location($resource))
{
$files['files'][] = $this->add_app('calendar', false, 'r'.$resource['res_id'],
'/'.groupdav_principals::resource2name($resource, $is_location).'/');
}
}
} }
return true; return true;
} }
@ -665,7 +715,7 @@ class groupdav extends HTTP_WebDAV_Server
{ {
foreach($shared as $id => $owner) foreach($shared as $id => $owner)
{ {
$file = $this->add_app($app,false,$id,$path.$app.'-'.$owner.'/'); $file = $this->add_app($app,false,$id,$path.$owner.'/');
// mark other users calendar as shared (iOS 5.0.1 AB does NOT display AB marked as shared!) // mark other users calendar as shared (iOS 5.0.1 AB does NOT display AB marked as shared!)
if ($app == 'calendar') $file['props']['resourcetype']['val'][] = self::mkprop(self::CALENDARSERVER,'shared',''); if ($app == 'calendar') $file['props']['resourcetype']['val'][] = self::mkprop(self::CALENDARSERVER,'shared','');
$files[] = $file; $files[] = $file;
@ -721,7 +771,12 @@ class groupdav extends HTTP_WebDAV_Server
{ {
if ($this->debug) error_log(__METHOD__."(app='$app', no_extra_types=$no_extra_types, user='$user', path='$path')"); if ($this->debug) error_log(__METHOD__."(app='$app', no_extra_types=$no_extra_types, user='$user', path='$path')");
$user_preferences = $GLOBALS['egw_info']['user']['preferences']; $user_preferences = $GLOBALS['egw_info']['user']['preferences'];
if ($user) if (is_string($user) && $user[0] == 'r' && ($resource = groupdav_principals::read_resource(substr($user, 1))))
{
$is_location = groupdav_principals::resource_is_location($resource);
list($principalType, $account_lid) = explode('/', groupdav_principals::resource2name($resource, $is_location, $displayname));
}
elseif ($user)
{ {
$account_lid = $this->accounts->id2name($user); $account_lid = $this->accounts->id2name($user);
if ($user >= 0 && $GLOBALS['egw']->preferences->account_id != $user) if ($user >= 0 && $GLOBALS['egw']->preferences->account_id != $user)
@ -730,22 +785,14 @@ class groupdav extends HTTP_WebDAV_Server
$user_preferences = $GLOBALS['egw']->preferences->read_repository(); $user_preferences = $GLOBALS['egw']->preferences->read_repository();
$GLOBALS['egw']->preferences->__construct($GLOBALS['egw_info']['user']['account_lid']); $GLOBALS['egw']->preferences->__construct($GLOBALS['egw_info']['user']['account_lid']);
} }
$principalType = $user < 0 ? 'groups' : 'users';
} }
else else
{ {
$account_lid = $GLOBALS['egw_info']['user']['account_lid']; $account_lid = $GLOBALS['egw_info']['user']['account_lid'];
}
$account = $this->accounts->read($account_lid);
if ($user < 0)
{
$principalType = 'groups';
}
else
{
$principalType = 'users'; $principalType = 'users';
} }
if (!isset($displayname)) $displayname = $this->account_name($user);
$props = array( $props = array(
'owner' => array(self::mkprop('href',$this->base_uri.'/principals/'.$principalType.'/'.$account_lid.'/')), 'owner' => array(self::mkprop('href',$this->base_uri.'/principals/'.$principalType.'/'.$account_lid.'/')),
@ -754,10 +801,10 @@ class groupdav extends HTTP_WebDAV_Server
switch ($app) switch ($app)
{ {
case 'inbox': case 'inbox':
$props['displayname'] = lang('Scheduling inbox').' '.$this->account_name($user); $props['displayname'] = lang('Scheduling inbox').' '.$displayname;
break; break;
case 'outbox': case 'outbox':
$props['displayname'] = lang('Scheduling outbox').' '.$this->account_name($user); $props['displayname'] = lang('Scheduling outbox').' '.$displayname;
break; break;
case 'addressbook': case 'addressbook':
if ($path == '/addressbook/') if ($path == '/addressbook/')
@ -773,7 +820,7 @@ class groupdav extends HTTP_WebDAV_Server
} }
// fall through // fall through
default: default:
$props['displayname'] = translation::convert(lang($app).' '.$this->account_name($user),$this->egw_charset,'utf-8'); $props['displayname'] = translation::convert(lang($app).' '.$displayname, $this->egw_charset, 'utf-8');
} }
// rfc 5995 (Use POST to add members to WebDAV collections): we use collection path with add-member query param // rfc 5995 (Use POST to add members to WebDAV collections): we use collection path with add-member query param
@ -842,7 +889,7 @@ class groupdav extends HTTP_WebDAV_Server
{ {
if (method_exists($handler,'extra_properties')) if (method_exists($handler,'extra_properties'))
{ {
$props = $handler->extra_properties($props,$this->account_name($account),$this->base_uri,$user,$path); $props = $handler->extra_properties($props, $displayname, $this->base_uri, $user, $path);
} }
// add ctag if handler implements it // add ctag if handler implements it
if (method_exists($handler,'getctag') && $this->prop_requested('getctag') === true) if (method_exists($handler,'getctag') && $this->prop_requested('getctag') === true)
@ -1433,14 +1480,30 @@ class groupdav extends HTTP_WebDAV_Server
} }
$parts = explode('/', $this->_unslashify($path)); $parts = explode('/', $this->_unslashify($path));
if (($account_id = $this->accounts->name2id($parts[0], 'account_lid')) || // /(resources|locations)/<resource-id>-<resource-name>/calendar
if ($parts[0] == 'resources' || $parts[0] == 'locations')
{
if (!empty($parts[1]))
{
$user = $parts[0].'/'.$parts[1];
array_shift($parts);
$res_id = (int)array_shift($parts);
if (!groupdav_principals::read_resource($res_id))
{
return false;
}
$account_id = 'r'.$res_id;
$app = 'calendar';
}
}
elseif (($account_id = $this->accounts->name2id($parts[0], 'account_lid')) ||
($account_id = $this->accounts->name2id($parts[0]=urldecode($parts[0])))) ($account_id = $this->accounts->name2id($parts[0]=urldecode($parts[0]))))
{ {
// /$user/$app/... // /$user/$app/...
$user = array_shift($parts); $user = array_shift($parts);
} }
$app = array_shift($parts); if (!isset($app)) $app = array_shift($parts);
// /addressbook-accounts/ // /addressbook-accounts/
if (!$account_id && $app == 'addressbook-accounts') if (!$account_id && $app == 'addressbook-accounts')
@ -1449,21 +1512,30 @@ class groupdav extends HTTP_WebDAV_Server
$user = 0; $user = 0;
$user_prefix = '/'; $user_prefix = '/';
} }
// shared calendars/addressbooks at /<currentuser>/(calendar|addressbook|infolog)-<username> // shared calendars/addressbooks at /<currentuser>/(calendar|addressbook|infolog|resource|location)-<username>
elseif ($account_id == $GLOBALS['egw_info']['user']['account_id'] && strpos($app, '-') !== false) elseif ($account_id == $GLOBALS['egw_info']['user']['account_id'] && strpos($app, '-') !== false)
{ {
$user_prefix = '/'.$GLOBALS['egw_info']['user']['account_lid'].'/'.$app;
list($app, $username) = explode('-', $app, 2); list($app, $username) = explode('-', $app, 2);
if ($username == 'accounts' && !$GLOBALS['egw_info']['user']['preferences']['addressbook']['hide_accounts']) if ($username == 'accounts' && !$GLOBALS['egw_info']['user']['preferences']['addressbook']['hide_accounts'])
{ {
$account_id = 0; $account_id = 0;
} }
elseif($app == 'resource' || $app == 'location')
{
if (!groupdav_principals::read_resource($res_id = (int)$username))
{
return false;
}
$account_id = 'r'.$res_id;
$app = 'calendar';
}
elseif (!($account_id = $this->accounts->name2id($username, 'account_lid')) && elseif (!($account_id = $this->accounts->name2id($username, 'account_lid')) &&
!($account_id = $this->accounts->name2id($username=urldecode($username)))) !($account_id = $this->accounts->name2id($username=urldecode($username))))
{ {
return false; return false;
} }
$user = $account_id; $user = $account_id;
$user_prefix = '/'.$GLOBALS['egw_info']['user']['account_lid'].'/'.$app.'-'.$username;
} }
elseif ($user) elseif ($user)
{ {

View File

@ -756,7 +756,7 @@ class groupdav_principals extends groupdav_handler
{ {
$files = array(); $files = array();
// add /pricipals/users/ entry // add /pricipals/users/ entry
$files[] = $this->add_collection('/principals/users/'); $files[] = $this->add_collection('/principals/users/', array('displayname' => lang('Users')));
if ($options['depth']) if ($options['depth'])
{ {
@ -822,7 +822,7 @@ class groupdav_principals extends groupdav_handler
{ {
$files = array(); $files = array();
// add /pricipals/users/ entry // add /pricipals/users/ entry
$files[] = $this->add_collection('/principals/groups/'); $files[] = $this->add_collection('/principals/groups/', array('displayname' => lang('Groups')));
if ($options['depth']) if ($options['depth'])
{ {
@ -1130,19 +1130,25 @@ class groupdav_principals extends groupdav_handler
'resource-id' => array(HTTP_WebDAV_Server::mkprop('href','urn:uuid:'.common::generate_uid('resources', $resource['res_id']))), 'resource-id' => array(HTTP_WebDAV_Server::mkprop('href','urn:uuid:'.common::generate_uid('resources', $resource['res_id']))),
// Calendarserver also reports empty email-address-set, thought iCal still does not show resources (only locations) // Calendarserver also reports empty email-address-set, thought iCal still does not show resources (only locations)
'email-address-set' => HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address-set',''), 'email-address-set' => HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address-set',''),
'calendar-home-set' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',array(
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$name.'/'))),
)); ));
} }
/** /**
* Get path of a resource-principal (relative to principal collection) * Get path of a resource-principal (relative to principal collection)
* *
* @param array $resource * @param array|int $resource
* @param boolean $is_location=null * @param boolean &$is_location=null
* @param string &$displayname=null on return displayname of resource * @param string &$displayname=null on return displayname of resource
* @return string eg. "locations/123-some-room" or "resouces/345-some-device" * @return string eg. "locations/123-some-room" or "resouces/345-some-device"
*/ */
protected function resource2name(array $resource, &$is_location=null, &$displayname=null) public static function resource2name($resource, &$is_location=null, &$displayname=null)
{ {
if (!is_array($resource) && !($resource = self::read_resource($resource)))
{
return null;
}
if (is_null($is_location)) $is_location = self::resource_is_location($resource); if (is_null($is_location)) $is_location = self::resource_is_location($resource);
$displayname = translation::convert($resource['name'], translation::charset(), 'utf-8'); $displayname = translation::convert($resource['name'], translation::charset(), 'utf-8');
@ -1165,7 +1171,7 @@ class groupdav_principals extends groupdav_handler
$str = htmlentities($str,ENT_QUOTES,translation::charset()); $str = htmlentities($str,ENT_QUOTES,translation::charset());
$str = str_replace(array_keys($extra),array_values($extra),$str); $str = str_replace(array_keys($extra),array_values($extra),$str);
$str = preg_replace('/&([aAuUoO])uml;/','\\1e',$str); // replace german umlauts with the letter plus one 'e' $str = preg_replace('/&([aAuUoO])uml;/','\\1e',$str); // replace german umlauts with the letter plus one 'e'
$str = preg_replace('/&([a-zA-Z])(grave|acute|circ|ring|cedil|tilde|slash|uml);/','\\1',$str); // remove all types of acents $str = preg_replace('/&([a-zA-Z])(grave|acute|circ|ring|cedil|tilde|slash|uml);/','\\1',$str); // remove all types of accents
$str = preg_replace('/&([a-zA-Z]+|#[0-9]+|);/','',$str); // remove all other entities $str = preg_replace('/&([a-zA-Z]+|#[0-9]+|);/','',$str); // remove all other entities
return $str; return $str;
@ -1186,16 +1192,38 @@ class groupdav_principals extends groupdav_handler
$config = config::read('resources'); $config = config::read('resources');
$location_cats = $config['location_cats'] ? explode(',', $config['location_cats']) : array(); $location_cats = $config['location_cats'] ? explode(',', $config['location_cats']) : array();
} }
if (!is_array($resource) && !($resource = self::read_resource($resource)))
{
return null;
}
return $resource['cat_id'] && in_array($resource['cat_id'], $location_cats);
}
/**
* Read a resource
*
* @param int $res_id resource-id
* @return array with values for res_id, cat_id and name
*/
public static function read_resource($res_id)
{
static $cache; // some per-request caching
if (isset(self::$all_resources) && isset(self::$all_resources[$res_id]))
{
return self::$all_resources[$res_id];
}
if (!isset($cache[$res_id]))
{
if (!isset(self::$resources)) self::$resources = new resources_bo(); if (!isset(self::$resources)) self::$resources = new resources_bo();
if (!is_array($resource)) if (!($cache[$res_id] = self::$resources->read($res_id)))
{
if (!($resource = self::$resources->read($resource)))
{ {
return null; return null;
} }
} }
return $resource['cat_id'] && in_array($resource['cat_id'], $location_cats); return $cache[$res_id];
} }
/** /**
@ -1220,10 +1248,12 @@ class groupdav_principals extends groupdav_handler
* *
* @return array of array with values for res_id, cat_id and name (no other values1) * @return array of array with values for res_id, cat_id and name (no other values1)
*/ */
protected function get_resources() public static function get_resources()
{ {
if (!isset(self::$all_resources)) if (!isset(self::$all_resources))
{ {
if (!isset(self::$resources)) self::$resources = new resources_bo();
self::$all_resources = array(); self::$all_resources = array();
$query = array( $query = array(
'show_bookable' => true, // ignore non-bookable resources 'show_bookable' => true, // ignore non-bookable resources
@ -1331,7 +1361,7 @@ class groupdav_principals extends groupdav_handler
$app = 'resources'; $app = 'resources';
if (!is_array($resource) || $resource['res_id'] == (int)$account) if (!is_array($resource) || $resource['res_id'] == (int)$account)
{ {
$resource = self::$resources->read((int)$account); $resource = self::read_resource((int)$account);
} }
$location = 'L'.$resource['cat_id']; $location = 'L'.$resource['cat_id'];
$right = $what == 'write' ? EGW_ACL_DIRECT_BOOKING : EGW_ACL_CALREAD; $right = $what == 'write' ? EGW_ACL_DIRECT_BOOKING : EGW_ACL_CALREAD;
@ -1502,7 +1532,8 @@ class groupdav_principals extends groupdav_handler
{ {
$files = array(); $files = array();
// add /pricipals/users/ entry // add /pricipals/users/ entry
$files[] = $this->add_collection('/principals/'.($do_locations ? 'locations/' : 'resources/')); $files[] = $this->add_collection('/principals/'.($do_locations ? 'locations/' : 'resources/'),
array('displayname' => $do_locations ? lang('Locations') : lang('Resources')));
if ($options['depth']) if ($options['depth'])
{ {
@ -1524,7 +1555,7 @@ class groupdav_principals extends groupdav_handler
} }
else else
{ {
if (!($resource = self::$resources->read((int)$name)) || ($is_location = self::resource_is_location($resource)) != $do_locations) if (!($resource = self::read_resource((int)$name)) || ($is_location = self::resource_is_location($resource)) != $do_locations)
{ {
return '404 Not Found'; return '404 Not Found';
} }

View File

@ -1,6 +1,7 @@
%1 email addresses inserted common de %1 E-Mail-Adressen eingefügt %1 email addresses inserted common de %1 E-Mail-Adressen eingefügt
%1 file common de %1 Datei %1 file common de %1 Datei
%1 is not executable by the webserver !!! common de %1 ist nicht ausführbar durch den Webserver !!! %1 is not executable by the webserver !!! common de %1 ist nicht ausführbar durch den Webserver !!!
%1 to sync groupdav de %1 zum synchronisieren
%1choose an other directory%2<br />or make %3 writeable by webserver common de %1Anderes Verzeichnis auswählen%2<br />oder %3 geben Sie dem Webserver Schreibrechte für dieses Verzeichnis. %1choose an other directory%2<br />or make %3 writeable by webserver common de %1Anderes Verzeichnis auswählen%2<br />oder %3 geben Sie dem Webserver Schreibrechte für dieses Verzeichnis.
%1egroupware%2 is a multi-user, web-based groupware suite written in %3php%4. common de %1EGroupware%2 ist eine, in %3PHP%4 programmierte, webbasierte, Mehrbenutzer Groupware Suite. %1egroupware%2 is a multi-user, web-based groupware suite written in %3php%4. common de %1EGroupware%2 ist eine, in %3PHP%4 programmierte, webbasierte, Mehrbenutzer Groupware Suite.
(session restored in %1 seconds) common de (Sitzung in %1 Sekunden wiederhergestellt) (session restored in %1 seconds) common de (Sitzung in %1 Sekunden wiederhergestellt)
@ -418,6 +419,8 @@ list common de Liste
list members common de Mitglieder anzeigen list members common de Mitglieder anzeigen
lithuania common de LITAUEN lithuania common de LITAUEN
local common de lokal local common de lokal
location calendars groupdav de Kalender von Räumen
locations common de Räume
logging / debuging groupdav de Logging / Fehlersuche logging / debuging groupdav de Logging / Fehlersuche
login common de Anmelden login common de Anmelden
loginid common de Benutzerkennung loginid common de Benutzerkennung
@ -596,6 +599,7 @@ replace common de Ersetzen
replace with common de Ersetzen durch replace with common de Ersetzen durch
requests and full responses to files directory common de Anfragen und komplette Antworten in das Dateiverzeichnis requests and full responses to files directory common de Anfragen und komplette Antworten in das Dateiverzeichnis
requests and truncated responses to apache error-log groupdav de Anfragen und gekürzte Antworten ins Apache error-log requests and truncated responses to apache error-log groupdav de Anfragen und gekürzte Antworten ins Apache error-log
resource calendars groupdav de Kalender von Ressourcen
resource type common de Ressource Typ resource type common de Ressource Typ
restore failed common de Wiederherstellung fehlgeschlagen restore failed common de Wiederherstellung fehlgeschlagen
returns a full list of accounts on the system. warning: this is return can be quite large common de Liefert eine vollständige Lister der Benutzerkonten auf diesem System. Warnung: Die Rückgabe kann sehr gross sein returns a full list of accounts on the system. warning: this is return can be quite large common de Liefert eine vollständige Lister der Benutzerkonten auf diesem System. Warnung: Die Rückgabe kann sehr gross sein

View File

@ -1,6 +1,7 @@
%1 email addresses inserted common en %1 email addresses inserted. %1 email addresses inserted common en %1 email addresses inserted.
%1 file common en %1 file %1 file common en %1 file
%1 is not executable by the webserver !!! common en %1 is not executable by the web server! %1 is not executable by the webserver !!! common en %1 is not executable by the web server!
%1 to sync groupdav en %1 to sync
%1choose an other directory%2<br />or make %3 writeable by webserver common en %1Choose an other directory%2<br />or make %3 writable by web server. %1choose an other directory%2<br />or make %3 writeable by webserver common en %1Choose an other directory%2<br />or make %3 writable by web server.
%1egroupware%2 is a multi-user, web-based groupware suite written in %3php%4. common en %1eGroupWare%2 is a multi-user, web-based groupware suite written in %3PHP%4. %1egroupware%2 is a multi-user, web-based groupware suite written in %3php%4. common en %1eGroupWare%2 is a multi-user, web-based groupware suite written in %3PHP%4.
(session restored in %1 seconds) common en Session restored in %1 seconds. (session restored in %1 seconds) common en Session restored in %1 seconds.
@ -419,6 +420,8 @@ list common en List
list members common en List members list members common en List members
lithuania common en LITHUANIA lithuania common en LITHUANIA
local common en Local local common en Local
location calendars groupdav en Location calendars
locations common en Locations
logging / debuging groupdav en Logging / debuging logging / debuging groupdav en Logging / debuging
login common en Login login common en Login
loginid common en Login ID loginid common en Login ID
@ -597,6 +600,7 @@ replace common en Replace
replace with common en Replace with replace with common en Replace with
requests and full responses to files directory common en Requests and full responses to files directory requests and full responses to files directory common en Requests and full responses to files directory
requests and truncated responses to apache error-log groupdav en Requests and truncated responses to Apache error-log requests and truncated responses to apache error-log groupdav en Requests and truncated responses to Apache error-log
resource calendars groupdav en Resource calendars
resource type common en Resource type resource type common en Resource type
restore failed common en Restore failed restore failed common en Restore failed
returns a full list of accounts on the system. warning: this is return can be quite large common en Returns a full list of accounts on the system. Warning: This is return can be quite large. returns a full list of accounts on the system. warning: this is return can be quite large common en Returns a full list of accounts on the system. Warning: This is return can be quite large.