mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 08:38:54 +01:00
Calendar can now store participants which are no accounts or contacts.
- as required by iCal/CalDAV/GroupDAV/SyncML - this also fixes problems with LDAP contacts, which have non-numeric ids - iCal code now converts to and from all participant types supported by eGroupWare: some types (eg. ressources) require that the clients keeps the new X-EGROUPWARE-UID attribute - calendar UI allows to enter email addresses via the addressbook search box (dont type search, but direct add)
This commit is contained in:
parent
5d50d41004
commit
cb9212e691
@ -7,7 +7,7 @@
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2004-7 by RalfBecker-At-outdoor-training.de
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
require_once(EGW_INCLUDE_ROOT.'/calendar/inc/class.socal.inc.php');
|
||||
@ -128,7 +128,7 @@ class bocal
|
||||
*/
|
||||
var $resources;
|
||||
/**
|
||||
* @internal
|
||||
* @internal
|
||||
* @var array $cached_event here we do some caching to read single events only once
|
||||
*/
|
||||
var $cached_event = array();
|
||||
@ -156,7 +156,7 @@ class bocal
|
||||
function bocal()
|
||||
{
|
||||
if ($this->debug > 0) $this->debug_message('bocal::bocal() started',True,$param);
|
||||
|
||||
|
||||
$this->so = new socal();
|
||||
$this->datetime = $GLOBALS['egw']->datetime;
|
||||
|
||||
@ -185,13 +185,49 @@ class bocal
|
||||
$this->resources[$data['type']] = $data + array('app' => $app);
|
||||
}
|
||||
}
|
||||
$this->resources['e'] = array(
|
||||
'type' => 'e',
|
||||
'info' => 'bocal::email_info',
|
||||
'app' => 'email',
|
||||
);
|
||||
$GLOBALS['egw']->session->appsession('resources','calendar',$this->resources);
|
||||
}
|
||||
}
|
||||
//echo "registered resources="; _debug_array($this->resources);
|
||||
|
||||
$this->config = config::read('calendar');
|
||||
}
|
||||
|
||||
/**
|
||||
* returns info about email addresses as participants
|
||||
*
|
||||
* @param int/array $ids single contact-id or array of id's
|
||||
* @return array
|
||||
*/
|
||||
static function email_info($ids)
|
||||
{
|
||||
if (!$ids) return null;
|
||||
|
||||
$data = array();
|
||||
foreach(!is_array($ids) ? array($ids) : $ids as $id)
|
||||
{
|
||||
$email = $id;
|
||||
$name = '';
|
||||
if (preg_match('/^(.*) *<([a-z0-9_.@-]{8,})>$/i',$email,$matches))
|
||||
{
|
||||
$name = $matches[1];
|
||||
$email = $matches[2];
|
||||
}
|
||||
$data[] = array(
|
||||
'res_id' => $id,
|
||||
'email' => $email,
|
||||
'rights' => EGW_ACL_READ_FOR_PARTICIPANTS,
|
||||
'name' => $name,
|
||||
);
|
||||
}
|
||||
//echo "<p>email_info(".print_r($ids,true).")="; _debug_array($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add group-members as participants with status 'G'
|
||||
*
|
||||
@ -244,14 +280,14 @@ class bocal
|
||||
* show_rejected if set rejected invitation are shown only when true, otherwise it depends on the cal-pref or a running query
|
||||
* ignore_acl if set and true no check_perms for a general EGW_ACL_READ grants is performed
|
||||
* enum_groups boolean if set and true, group-members will be added as participants with status 'G'
|
||||
* @return array of events or array with YYYYMMDD strings / array of events pairs (depending on $daywise param)
|
||||
* @return array of events or array with YYYYMMDD strings / array of events pairs (depending on $daywise param)
|
||||
* or false if there are no read-grants from _any_ of the requested users
|
||||
*/
|
||||
function &search($params)
|
||||
{
|
||||
$params_in = $params;
|
||||
|
||||
if (!isset($params['users']) || !$params['users'] ||
|
||||
if (!isset($params['users']) || !$params['users'] ||
|
||||
count($params['users']) == 1 && isset($params['users'][0]) && !$params['users'][0]) // null or '' casted to an array
|
||||
{
|
||||
// for a search use all account you have read grants from
|
||||
@ -288,7 +324,7 @@ class bocal
|
||||
foreach($members as $member)
|
||||
{
|
||||
// use only members which gave the user a read-grant
|
||||
if (!in_array($member['account_id'],$users) &&
|
||||
if (!in_array($member['account_id'],$users) &&
|
||||
($params['ignore_acl'] || $this->check_perms(EGW_ACL_READ,0,$member['account_id'])))
|
||||
{
|
||||
$users[] = $member['account_id'];
|
||||
@ -311,7 +347,7 @@ class bocal
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we have no grants from the given user(s), we directly return no events / an empty array,
|
||||
// if we have no grants from the given user(s), we directly return no events / an empty array,
|
||||
// as calling the so-layer without users would give the events of all users (!)
|
||||
if (!count($users))
|
||||
{
|
||||
@ -340,7 +376,7 @@ class bocal
|
||||
$users,$cat_id,$filter,$params['query'],$offset,(int)$params['num_rows'],$params['order'],$show_rejected);
|
||||
$this->total = $this->so->total;
|
||||
$this->db2data($events,isset($params['date_format']) ? $params['date_format'] : 'ts');
|
||||
|
||||
|
||||
// socal::search() returns rejected group-invitations, as only the user not also the group is rejected
|
||||
// as we cant remove them efficiantly in SQL, we kick them out here, but only if just one user is displayed
|
||||
$remove_rejected_by_user = !$show_rejected && count($params['users']) == 1 ? $params['users'][0] : false;
|
||||
@ -397,7 +433,7 @@ class bocal
|
||||
if ($ymd != ($last = $this->date2string($e_end)))
|
||||
{
|
||||
$daysEvents[$last][] =& $events[$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
$events =& $daysEvents;
|
||||
if ($this->debug && ($this->debug > 2 || $this->debug == 'search'))
|
||||
@ -430,7 +466,7 @@ class bocal
|
||||
}
|
||||
return $events;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears all non-private info from a privat event
|
||||
*
|
||||
@ -452,7 +488,7 @@ class bocal
|
||||
'non_blocking' => $event['non_blocking'],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check and evtl. move the horizont (maximum date for unlimited recuring events) to a new date
|
||||
*
|
||||
@ -466,7 +502,7 @@ class bocal
|
||||
$this->debug_message('bocal::check_move_horizont(%1) horizont=%2',true,$new_horizont,$this->config['horizont']);
|
||||
}
|
||||
$new_horizont = $this->date2ts($new_horizont,true); // now we are in server-time, where this function operates
|
||||
|
||||
|
||||
if ($new_horizont > time()+1000*DAY_s) // some user tries to "look" more then 1000 days in the future
|
||||
{
|
||||
if ($this->debug == 'check_move_horizont') $this->debug_message('bocal::check_move_horizont(%1) horizont=%2 new horizont more then 1000 days from now --> ignoring it',true,$new_horizont,$this->config['horizont']);
|
||||
@ -500,7 +536,7 @@ class bocal
|
||||
// update the horizont
|
||||
$config =& CreateObject('phpgwapi.config','calendar');
|
||||
$config->save_value('horizont',$this->config['horizont'],'calendar');
|
||||
|
||||
|
||||
if ($this->debug == 'check_move_horizont') $this->debug_message('bocal::check_move_horizont(%1) new horizont=%2, exiting',true,$new_horizont,$this->config['horizont']);
|
||||
}
|
||||
|
||||
@ -523,7 +559,7 @@ class bocal
|
||||
$event['participants'] = $event_read['participants'];
|
||||
}
|
||||
if (!$start) $start = $event['start'];
|
||||
|
||||
|
||||
$events = array();
|
||||
$this->insert_all_repetitions($event,$start,$this->date2ts($this->config['horizont'],true),$events,null);
|
||||
|
||||
@ -532,7 +568,7 @@ class bocal
|
||||
$this->so->recurrence($event['id'],$this->date2ts($event['start'],true),$this->date2ts($event['end'],true),$event['participants']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* convert data read from the db, eg. convert server to user-time
|
||||
*
|
||||
@ -569,7 +605,7 @@ class bocal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* convert a date from server to user-time
|
||||
*
|
||||
@ -579,7 +615,7 @@ class bocal
|
||||
function date2usertime($ts,$date_format='ts')
|
||||
{
|
||||
if (empty($ts)) return $ts;
|
||||
|
||||
|
||||
switch ($date_format)
|
||||
{
|
||||
case 'ts':
|
||||
@ -612,7 +648,7 @@ class bocal
|
||||
|
||||
if ($ignore_acl || is_array($ids) || ($return = $this->check_perms(EGW_ACL_READ,$ids,0,$date_format,$date)))
|
||||
{
|
||||
if (is_array($ids) || !isset($this->cached_event['id']) || $this->cached_event['id'] != $ids ||
|
||||
if (is_array($ids) || !isset($this->cached_event['id']) || $this->cached_event['id'] != $ids ||
|
||||
$this->cached_event_date_format != $date_format ||
|
||||
$this->cached_event['recur_type'] != MCAL_RECUR_NONE && !is_null($date) && (!$date || $this->cached_event['start'] < $date))
|
||||
{
|
||||
@ -621,7 +657,7 @@ class bocal
|
||||
if ($events)
|
||||
{
|
||||
$this->db2data($events,$date_format);
|
||||
|
||||
|
||||
if (is_array($ids))
|
||||
{
|
||||
$return =& $events;
|
||||
@ -672,7 +708,7 @@ class bocal
|
||||
$this->debug_message('bocal::insert_all_repitions(%1,%2,%3,&$event,%4)',true,$event,$start,$end,$recur_exceptions);
|
||||
}
|
||||
$start_in = $start; $end_in = $end;
|
||||
|
||||
|
||||
$start = $this->date2ts($start);
|
||||
$end = $this->date2ts($end);
|
||||
$event_start_ts = $this->date2ts($event['start']);
|
||||
@ -684,7 +720,7 @@ class bocal
|
||||
}
|
||||
$id = $event['id'];
|
||||
$event_start_arr = $this->date2array($event['start']);
|
||||
// to be able to calculate the repetitions as difference to the start-date,
|
||||
// to be able to calculate the repetitions as difference to the start-date,
|
||||
// both need to be calculated without daylight saving: mktime(,,,,,,0)
|
||||
$event_start_daybegin_ts = adodb_mktime(0,0,0,$event_start_arr['month'],$event_start_arr['day'],$event_start_arr['year'],0);
|
||||
|
||||
@ -710,7 +746,7 @@ class bocal
|
||||
$search_date_ymd = (int)$this->date2string($ts);
|
||||
|
||||
$have_exception = !is_null($recur_exceptions) && isset($recur_exceptions[$search_date_ymd]);
|
||||
|
||||
|
||||
if (!$have_exception) // no execption by an edited event => check the deleted ones
|
||||
{
|
||||
foreach((array)$event['recur_exception'] as $exception_ts)
|
||||
@ -731,7 +767,7 @@ class bocal
|
||||
$search_date_month = adodb_date('m',$ts);
|
||||
$search_date_day = adodb_date('d',$ts);
|
||||
$search_date_dow = adodb_date('w',$ts);
|
||||
// to be able to calculate the repetitions as difference to the start-date,
|
||||
// to be able to calculate the repetitions as difference to the start-date,
|
||||
// both need to be calculated without daylight saving: mktime(,,,,,,0)
|
||||
$search_beg_day = adodb_mktime(0,0,0,$search_date_month,$search_date_day,$search_date_year,0);
|
||||
|
||||
@ -879,10 +915,32 @@ class bocal
|
||||
function resource_info($uid)
|
||||
{
|
||||
static $res_info_cache = array();
|
||||
|
||||
|
||||
if (!isset($res_info_cache[$uid]))
|
||||
{
|
||||
list($res_info_cache[$uid]) = $this->resources[$uid{0}]['info'] ? ExecMethod($this->resources[$uid{0}]['info'],substr($uid,1)) : false;
|
||||
if (is_numeric($uid))
|
||||
{
|
||||
$info = array(
|
||||
'res_id' => $uid,
|
||||
'email' => $GLOBALS['egw']->accounts->id2name($uid,'account_email'),
|
||||
'name' => trim($GLOBALS['egw']->accounts->id2name($uid,'account_firstname'). ' ' .
|
||||
$GLOBALS['egw']->accounts->id2name($uid,'account_lastname')),
|
||||
'type' => $GLOBALS['egw']->accounts->get_type($uid),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
list($info) = $this->resources[$uid[0]]['info'] ? ExecMethod($this->resources[$uid[0]]['info'],substr($uid,1)) : false;
|
||||
if ($info)
|
||||
{
|
||||
$info['type'] = $uid[0];
|
||||
if (!$info['email'] && $info['responsible'])
|
||||
{
|
||||
$info['email'] = $GLOBALS['egw']->accounts->id2name($info['responsible'],'account_email');
|
||||
}
|
||||
}
|
||||
}
|
||||
$res_info_cache[$uid] = $info;
|
||||
}
|
||||
if ($this->debug && ($this->debug > 2 || $this->debug == 'resource_info'))
|
||||
{
|
||||
@ -938,7 +996,7 @@ class bocal
|
||||
}
|
||||
$user = $GLOBALS['egw_info']['user']['account_id'];
|
||||
$grants = $this->grants[$owner];
|
||||
|
||||
|
||||
if (is_array($event) && $needed == EGW_ACL_READ)
|
||||
{
|
||||
// Check if the $user is one of the participants or has a read-grant from one of them
|
||||
@ -946,7 +1004,7 @@ class bocal
|
||||
//
|
||||
foreach($event['participants'] as $uid => $accept)
|
||||
{
|
||||
if ($uid == $user || $uid < 0 && in_array($user,$GLOBALS['egw']->accounts->members($uid,true)))
|
||||
if ($uid == $user || $uid < 0 && in_array($user,$GLOBALS['egw']->accounts->members($uid,true)))
|
||||
{
|
||||
// if we are a participant, we have an implicite READ and PRIVAT grant
|
||||
$grants |= EGW_ACL_READ | EGW_ACL_PRIVATE;
|
||||
@ -956,14 +1014,14 @@ class bocal
|
||||
{
|
||||
// if we have a READ grant from a participant, we dont give an implicit privat grant too
|
||||
$grants |= EGW_ACL_READ;
|
||||
// we cant break here, as we might be a participant too, and would miss the privat grant
|
||||
// we cant break here, as we might be a participant too, and would miss the privat grant
|
||||
}
|
||||
elseif (!is_numeric($uid))
|
||||
{
|
||||
// if we have a resource as participant
|
||||
$resource = $this->resource_info($uid);
|
||||
$grants |= $resource['rights'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1105,10 +1163,10 @@ class bocal
|
||||
else
|
||||
{
|
||||
$date = $this->date2ts($date,False);
|
||||
|
||||
|
||||
// if timezone is requested, we dont need to convert to user-time
|
||||
if (($tz_used = substr($format,-1)) == 'O' || $tz_used == 'Z') $server2user = false;
|
||||
|
||||
|
||||
if ($server2user && substr($format,-1) )
|
||||
{
|
||||
$date += $this->tz_offset_s;
|
||||
@ -1249,7 +1307,7 @@ class bocal
|
||||
|
||||
if ($display_day)
|
||||
{
|
||||
$range = lang(adodb_date('l',$first['raw'])).($this->common_prefs['dateformat']{0} != 'd' ? ' ' : ', ');
|
||||
$range = lang(adodb_date('l',$first['raw'])).($this->common_prefs['dateformat'][0] != 'd' ? ' ' : ', ');
|
||||
}
|
||||
for ($i = 0; $i < 5; $i += 2)
|
||||
{
|
||||
@ -1319,7 +1377,7 @@ class bocal
|
||||
}
|
||||
return $range;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays a timespan, eg. $both ? "10:00 - 13:00: 3h" (10:00 am - 1 pm: 3h) : "10:00 3h" (10:00 am 3h)
|
||||
*
|
||||
@ -1334,7 +1392,7 @@ class bocal
|
||||
$duration = floor($duration/60).lang('h').($duration%60 ? $duration%60 : '');
|
||||
|
||||
$timespan = $t = $GLOBALS['egw']->common->formattime(sprintf('%02d',$start_m/60),sprintf('%02d',$start_m%60));
|
||||
|
||||
|
||||
if ($both) // end-time too
|
||||
{
|
||||
$timespan .= ' - '.$GLOBALS['egw']->common->formattime(sprintf('%02d',$end_m/60),sprintf('%02d',$end_m%60));
|
||||
@ -1357,14 +1415,18 @@ class bocal
|
||||
function participant_name($id,$use_type=false)
|
||||
{
|
||||
static $id2lid = array();
|
||||
|
||||
|
||||
if ($use_type && $use_type != 'u') $id = $use_type.$id;
|
||||
|
||||
if (!isset($id2lid[$id]))
|
||||
{
|
||||
if (!is_numeric($id))
|
||||
{
|
||||
$id2lid[$id] = egw_link::title($this->resources[$id{0}]['app'],substr($id,1));
|
||||
$id2lid[$id] = '#'.$id;
|
||||
if (($info = $this->resource_info($id)))
|
||||
{
|
||||
$id2lid[$id] = $info['name'] ? $info['name'] : $info['email'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1507,12 +1569,12 @@ class bocal
|
||||
|
||||
return $users + $groups; // users first and then groups, both alphabeticaly
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert the recure-information of an event, into a human readable string
|
||||
*
|
||||
* @param array $event
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
function recure2string($event)
|
||||
{
|
||||
@ -1588,7 +1650,7 @@ class bocal
|
||||
}
|
||||
$this->holidays->prepare_read_holidays($year);
|
||||
$this->cached_holidays[$year] = $this->holidays->read_holiday();
|
||||
|
||||
|
||||
// search for birthdays
|
||||
if ($GLOBALS['egw_info']['server']['hide_birthdays'] != 'yes')
|
||||
{
|
||||
@ -1613,7 +1675,7 @@ class bocal
|
||||
}
|
||||
}
|
||||
}
|
||||
// store holidays and birthdays in the session
|
||||
// store holidays and birthdays in the session
|
||||
$this->cached_holidays = $GLOBALS['egw']->session->appsession('holidays','calendar',$this->cached_holidays);
|
||||
}
|
||||
if ((int) $this->debug >= 2 || $this->debug == 'read_holidays')
|
||||
@ -1622,10 +1684,10 @@ class bocal
|
||||
}
|
||||
return $this->cached_holidays[$year];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get title for an event identified by $event
|
||||
*
|
||||
*
|
||||
* Is called as hook to participate in the linking
|
||||
*
|
||||
* @param int/array $entry int cal_id or array with event
|
||||
@ -1661,7 +1723,7 @@ class bocal
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook called by link-class to include calendar in the appregistry of the linkage
|
||||
*
|
||||
@ -1682,7 +1744,7 @@ class bocal
|
||||
'menuaction' => 'calendar.uiforms.edit',
|
||||
),
|
||||
'add_app' => 'link_app',
|
||||
'add_id' => 'link_id',
|
||||
'add_id' => 'link_id',
|
||||
'add_popup' => '750x400',
|
||||
);
|
||||
}
|
||||
@ -1744,7 +1806,7 @@ class bocal
|
||||
$GLOBALS['egw']->preferences->save_repository(False,'default');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the freebusy URL of a user
|
||||
*
|
||||
@ -1755,7 +1817,7 @@ class bocal
|
||||
{
|
||||
if (is_numeric($user)) $user = $GLOBALS['egw']->accounts->id2name($user);
|
||||
|
||||
return (!$GLOBALS['egw_info']['server']['webserver_url'] || $GLOBALS['egw_info']['server']['webserver_url']{0} == '/' ?
|
||||
return (!$GLOBALS['egw_info']['server']['webserver_url'] || $GLOBALS['egw_info']['server']['webserver_url'][0] == '/' ?
|
||||
($_SERVER['HTTPS'] ? 'https://' : 'http://').$_SERVER['HTTP_HOST'] : '').
|
||||
$GLOBALS['egw_info']['server']['webserver_url'].'/calendar/freebusy.php?user='.urlencode($user).
|
||||
($pw ? '&password='.urlencode($pw) : '');
|
||||
|
@ -155,7 +155,7 @@ class bocalupdate extends bocal
|
||||
$users = array_unique($users);
|
||||
}
|
||||
$users[] = $uid;
|
||||
if (in_array($uid{0},$types_with_quantity))
|
||||
if (in_array($uid[0],$types_with_quantity))
|
||||
{
|
||||
$quantity[$uid] = max(1,(int) substr($status,2));
|
||||
}
|
||||
@ -188,19 +188,19 @@ class bocalupdate extends bocal
|
||||
$common_parts = array_intersect($users,array_keys($overlap['participants']));
|
||||
foreach($common_parts as $n => $uid)
|
||||
{
|
||||
if ($overlap['participants'][$uid]{0} == 'R')
|
||||
if ($overlap['participants'][$uid][0] == 'R')
|
||||
{
|
||||
unset($common_parts[$uid]);
|
||||
continue;
|
||||
}
|
||||
if (is_numeric($uid) || !in_array($uid{0},$types_with_quantity))
|
||||
if (is_numeric($uid) || !in_array($uid[0],$types_with_quantity))
|
||||
{
|
||||
continue; // no quantity check: quantity allways 1 ==> conflict
|
||||
}
|
||||
if (!isset($max_quantity[$uid]))
|
||||
{
|
||||
$res_info = $this->resource_info($uid);
|
||||
$max_quantity[$uid] = $res_info[$this->resources[$uid{0}]['max_quantity']];
|
||||
$max_quantity[$uid] = $res_info[$this->resources[$uid[0]]['max_quantity']];
|
||||
}
|
||||
$quantity[$uid] += max(1,(int) substr($overlap['participants'][$uid],2));
|
||||
if ($quantity[$uid] <= $max_quantity[$uid])
|
||||
@ -741,7 +741,7 @@ class bocalupdate extends bocal
|
||||
*/
|
||||
function check_status_perms($uid,$event)
|
||||
{
|
||||
if ($uid{0} == 'c') // for contact we use the owner of the event
|
||||
if ($uid[0] == 'c' || $uid['0'] == 'e') // for contact we use the owner of the event
|
||||
{
|
||||
if (!is_array($event) && !($event = $this->read($event))) return false;
|
||||
|
||||
@ -774,7 +774,7 @@ class bocalupdate extends bocal
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (($Ok = $this->so->set_status($cal_id,is_numeric($uid)?'u':$uid{0},is_numeric($uid)?$uid:substr($uid,1),$status,$recur_date ? $this->date2ts($recur_date,true) : 0)))
|
||||
if (($Ok = $this->so->set_status($cal_id,is_numeric($uid)?'u':$uid[0],is_numeric($uid)?$uid:substr($uid,1),$status,$recur_date ? $this->date2ts($recur_date,true) : 0)))
|
||||
{
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,'modify',time());
|
||||
|
||||
@ -850,7 +850,7 @@ class bocalupdate extends bocal
|
||||
$eventStart_arr = $this->date2array($event['start']); // give this as 'date' to the link to pick the right recurrence for the participants state
|
||||
$link = $GLOBALS['egw_info']['server']['webserver_url'].'/index.php?menuaction=calendar.uiforms.edit&cal_id='.$event['id'].'&date='.$eventStart_arr['full'].'&no_popup=1';
|
||||
// if url is only a path, try guessing the rest ;-)
|
||||
if ($link{0} == '/')
|
||||
if ($link[0] == '/')
|
||||
{
|
||||
$link = ($GLOBALS['egw_info']['server']['enforce_ssl'] || $_SERVER['HTTPS'] ? 'https://' : 'http://').
|
||||
($GLOBALS['egw_info']['server']['hostname'] ? $GLOBALS['egw_info']['server']['hostname'] : $_SERVER['HTTP_HOST']).
|
||||
|
@ -191,14 +191,9 @@
|
||||
case 'ATTENDEE':
|
||||
foreach((array)$event['participants'] as $uid => $status)
|
||||
{
|
||||
// ToDo, this needs to deal with resources too!!!
|
||||
if (!is_numeric($uid)) continue;
|
||||
|
||||
$mailto = $GLOBALS['egw']->accounts->id2name($uid,'account_email');
|
||||
$cn = trim($GLOBALS['egw']->accounts->id2name($uid,'account_firstname'). ' ' .
|
||||
$GLOBALS['egw']->accounts->id2name($uid,'account_lastname'));
|
||||
if (!($info = $this->resource_info($uid))) continue;
|
||||
// RB: MAILTO href contains only the email-address, NO cn!
|
||||
$attributes['ATTENDEE'][] = $mailto ? 'MAILTO:'.$mailto : '';
|
||||
$attributes['ATTENDEE'][] = $info['email'] ? 'MAILTO:'.$info['email'] : '';
|
||||
// ROLE={CHAIR|REQ-PARTICIPANT|OPT-PARTICIPANT|NON-PARTICIPANT} NOT used by eGW atm.
|
||||
$role = $uid == $event['owner'] ? 'CHAIR' : 'REQ-PARTICIPANT';
|
||||
// RSVP={TRUE|FALSE} // resonse expected, not set in eGW => status=U
|
||||
@ -206,7 +201,7 @@
|
||||
// PARTSTAT={NEEDS-ACTION|ACCEPTED|DECLINED|TENTATIVE|DELEGATED|COMPLETED|IN-PROGRESS} everything from delegated is NOT used by eGW atm.
|
||||
$status = $this->status_egw2ical[$status];
|
||||
// CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN}
|
||||
switch (is_numeric($uid) ? $GLOBALS['egw']->accounts->get_type($uid) : $uid{0})
|
||||
switch ($info['type'])
|
||||
{
|
||||
case 'g':
|
||||
$cutype = 'GROUP';
|
||||
@ -214,21 +209,22 @@
|
||||
case 'r':
|
||||
$cutype = 'RESOURCE';
|
||||
break;
|
||||
case 'u':
|
||||
case 'u': // account
|
||||
case 'c': // contact
|
||||
case 'e': // email address
|
||||
$cutype = 'INDIVIDUAL';
|
||||
break;
|
||||
default:
|
||||
$cutype = 'UNKNOWN';
|
||||
$cutype = 'INDIVIDUAL';
|
||||
break;
|
||||
};
|
||||
$parameters['ATTENDEE'][] = array(
|
||||
'CN' => $cn,
|
||||
'CN' => $info['name'],
|
||||
'ROLE' => $role,
|
||||
'PARTSTAT' => $status,
|
||||
'CUTYPE' => $cutype,
|
||||
'RSVP' => $rsvp,
|
||||
);
|
||||
)+($info['type'] != 'e' ? array('X-EGROUPWARE-UID' => $uid) : array());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -563,7 +559,7 @@
|
||||
break;
|
||||
case 'RRULE':
|
||||
$recurence = $attributes['value'];
|
||||
$type = preg_match('/FREQ=([^;: ]+)/i',$recurence,$matches) ? $matches[1] : $recurence{0};
|
||||
$type = preg_match('/FREQ=([^;: ]+)/i',$recurence,$matches) ? $matches[1] : $recurence[0];
|
||||
// vCard 2.0 values for all types
|
||||
if (preg_match('/UNTIL=([0-9T]+)/',$recurence,$matches))
|
||||
{
|
||||
@ -768,28 +764,46 @@
|
||||
}
|
||||
break;
|
||||
case 'ATTENDEE':
|
||||
if (preg_match('/MAILTO:([@.a-z0-9_-]+)/i',$attributes['value'],$matches) &&
|
||||
($uid = $GLOBALS['egw']->accounts->name2id($matches[1],'account_email')))
|
||||
if (preg_match('/MAILTO:([@.a-z0-9_-]+)/i',$attributes['value'],$matches) ||
|
||||
preg_match('/<([@.a-z0-9_-]+)>/i',$attributes['value'],$matches))
|
||||
{
|
||||
$email = $matches[1];
|
||||
}
|
||||
elseif(strpos($attributes['value'],'@') !== false)
|
||||
{
|
||||
$email = $attributes['value'];
|
||||
}
|
||||
if (($uid = $attributes['params']['X-EGROUPWARE-UID']) &&
|
||||
($info = $this->resource_info($uid)) && $info['email'] == $email)
|
||||
{
|
||||
$event['participants'][$uid] = isset($attributes['params']['PARTSTAT']) ?
|
||||
// we use the (checked) X-EGROUPWARE-UID
|
||||
}
|
||||
/*elseif($attributes['params']['CUTYPE'] == 'RESOURCE')
|
||||
{
|
||||
|
||||
}*/
|
||||
elseif($attributes['value'] == 'Unknown')
|
||||
{
|
||||
$uid = $GLOBALS['egw_info']['user']['account_id'];
|
||||
}
|
||||
elseif (($uid = $GLOBALS['egw']->accounts->name2id($email,'account_email')))
|
||||
{
|
||||
// we use the account we found
|
||||
}
|
||||
elseif ((list($data) = ExecMethod2('addressbook.bocontacts.search',array(
|
||||
'email' => $email,
|
||||
'email_home' => $email,
|
||||
),true,'','','',false,'OR')))
|
||||
{
|
||||
$uid = 'c'.$data['id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$uid = 'e'.($attributes['params']['CN'] ? $attributes['params']['CN'].' <'.$email.'>' : $email);
|
||||
}
|
||||
$event['participants'][$uid] = isset($attributes['params']['PARTSTAT']) ?
|
||||
$this->status_ical2egw[strtoupper($attributes['params']['PARTSTAT'])] :
|
||||
($uid == $event['owner'] ? 'A' : 'U');
|
||||
}
|
||||
|
||||
if (preg_match('/<([@.a-z0-9_-]+)>/i',$attributes['value'],$matches)) {
|
||||
$uid = '';
|
||||
$uid = $GLOBALS['egw']->accounts->name2id($matches[1],'account_email');
|
||||
if(!empty($uid)) {
|
||||
$event['participants'][$uid] = isset($attributes['params']['PARTSTAT']) ?
|
||||
$this->status_ical2egw[strtoupper($attributes['params']['PARTSTAT'])] :
|
||||
($uid == $event['owner'] ? 'A' : 'U');
|
||||
}
|
||||
}
|
||||
|
||||
if($attributes['value'] == 'Unknown') {
|
||||
$event['participants'][$GLOBALS['egw_info']['user']['account_id']] = 'A';
|
||||
}
|
||||
|
||||
break;
|
||||
case 'ORGANIZER': // will be written direct to the event
|
||||
if (preg_match('/MAILTO:([@.a-z0-9_-]+)/i',$attributes['value'],$matches) &&
|
||||
@ -1195,7 +1209,7 @@
|
||||
break;
|
||||
case 'RRULE':
|
||||
$recurence = $attributes['value'];
|
||||
$type = preg_match('/FREQ=([^;: ]+)/i',$recurence,$matches) ? $matches[1] : $recurence{0};
|
||||
$type = preg_match('/FREQ=([^;: ]+)/i',$recurence,$matches) ? $matches[1] : $recurence[0];
|
||||
// vCard 2.0 values for all types
|
||||
if (preg_match('/UNTIL=([0-9T]+)/',$recurence,$matches))
|
||||
{
|
||||
|
@ -690,8 +690,8 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
* combines user_type and user_id into a single string or integer (for users)
|
||||
*
|
||||
* @param string $user_type 1-char type: 'u' = user, ...
|
||||
* @param int $user_id id
|
||||
* @return string/int combined id
|
||||
* @param string|int $user_id id
|
||||
* @return string|int combined id
|
||||
*/
|
||||
function combine_user($user_type,$user_id)
|
||||
{
|
||||
@ -705,9 +705,9 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
/**
|
||||
* splits the combined user_type and user_id into a single values
|
||||
*
|
||||
* @param string $user_type 1-char type: 'u' = user, ...
|
||||
* @param int $user_id id
|
||||
* @return string/int
|
||||
* @param string|int $uid
|
||||
* @param string &$user_type 1-char type: 'u' = user, ...
|
||||
* @param string|int &$user_id id
|
||||
*/
|
||||
function split_user($uid,&$user_type,&$user_id)
|
||||
{
|
||||
@ -719,7 +719,7 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
else
|
||||
{
|
||||
$user_type = $uid[0];
|
||||
$user_id = (int) substr($uid,1);
|
||||
$user_id = substr($uid,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ class uical
|
||||
var $debug=false;
|
||||
/**
|
||||
* instance of the bocal or bocalupdate class
|
||||
*
|
||||
*
|
||||
* @var bocalupdate
|
||||
*/
|
||||
var $bo;
|
||||
@ -116,7 +116,7 @@ class uical
|
||||
* @var string $view menuaction of the selected view
|
||||
*/
|
||||
var $view_menuaction;
|
||||
|
||||
|
||||
/**
|
||||
* @var int $first first day of the shown view
|
||||
*/
|
||||
@ -162,11 +162,11 @@ class uical
|
||||
$this->manage_states($set_states);
|
||||
|
||||
$GLOBALS['uical'] = &$this; // make us available for ExecMethod, else it creates a new instance
|
||||
|
||||
|
||||
// calendar does not work with hidden sidebox atm.
|
||||
unset($GLOBALS['egw_info']['user']['preferences']['common']['auto_hide_sidebox']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks and terminates (or returns for home) with a message if $this->owner include a user/resource we have no read-access to
|
||||
*
|
||||
@ -187,7 +187,7 @@ class uical
|
||||
if (!$this->bo->check_perms(EGW_ACL_READ|EGW_ACL_READ_FOR_PARTICIPANTS,0,$member))
|
||||
{
|
||||
$no_access_group[$member] = $this->bo->participant_name($member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (!$this->bo->check_perms(EGW_ACL_READ|EGW_ACL_READ_FOR_PARTICIPANTS,0,$owner))
|
||||
@ -198,7 +198,7 @@ class uical
|
||||
if (count($no_access))
|
||||
{
|
||||
$msg = '<p class="redItalic" align="center">'.lang('Access denied to the calendar of %1 !!!',implode(', ',$no_access))."</p>\n";
|
||||
|
||||
|
||||
if ($GLOBALS['egw_info']['flags']['currentapp'] == 'home')
|
||||
{
|
||||
return $msg;
|
||||
@ -217,7 +217,7 @@ class uical
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* show the egw-framework plus possible messages ($_GET['msg'] and $this->group_warning from check_owner_access)
|
||||
*/
|
||||
@ -225,7 +225,7 @@ class uical
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['include_xajax'] = true;
|
||||
$GLOBALS['egw']->common->egw_header();
|
||||
|
||||
|
||||
if ($_GET['msg']) echo '<p class="redItalic" align="center">'.html::htmlspecialchars($_GET['msg'])."</p>\n";
|
||||
|
||||
if ($this->group_warning) echo '<p class="redItalic" align="center">'.$this->group_warning."</p>\n";
|
||||
@ -282,11 +282,11 @@ class uical
|
||||
}
|
||||
else // change only the owners of the given type
|
||||
{
|
||||
$res_type = is_numeric($set_owners[0]) ? false : $set_owners[0]{0};
|
||||
$res_type = is_numeric($set_owners[0]) ? false : $set_owners[0][0];
|
||||
$owners = explode(',',$states['owner'] ? $states['owner'] : $default);
|
||||
foreach($owners as $key => $owner)
|
||||
{
|
||||
if (!$res_type && is_numeric($owner) || $res_type && $owner{0} == $res_type)
|
||||
if (!$res_type && is_numeric($owner) || $res_type && $owner[0] == $res_type)
|
||||
{
|
||||
unset($owners[$key]);
|
||||
}
|
||||
@ -342,7 +342,7 @@ class uical
|
||||
{
|
||||
if ($this->cal_prefs['planner_start_with_group'] > 0) $this->cal_prefs['planner_start_with_group'] *= -1; // fix old 1.0 pref
|
||||
|
||||
if (!$states_session && !$_GET['menuaction']) $this->view = ''; // first call to calendar
|
||||
if (!$states_session && !$_GET['menuaction']) $this->view = ''; // first call to calendar
|
||||
|
||||
if ($func == 'planner' && $this->view != 'planner' && $this->owner == $this->user)
|
||||
{
|
||||
@ -390,7 +390,7 @@ class uical
|
||||
// icons for single user, multiple users or group(s) and resources
|
||||
foreach($event['participants'] as $uid => $status)
|
||||
{
|
||||
if(is_numeric($uid) || $uid{0} == 'c')
|
||||
if(is_numeric($uid) || !isset($this->bo->resources[$uid[0]]['icon']))
|
||||
{
|
||||
if (isset($icons['single']) || $GLOBALS['egw']->accounts->get_type($uid) == 'g')
|
||||
{
|
||||
@ -401,12 +401,12 @@ class uical
|
||||
{
|
||||
$icons['single'] = html::image('calendar','single');
|
||||
}
|
||||
}
|
||||
elseif(!isset($icons[$uid{0}]) && isset($this->bo->resources[$uid{0}]) && isset($this->bo->resources[$uid{0}]['icon']))
|
||||
}
|
||||
elseif(!isset($icons[$uid[0]]) && isset($this->bo->resources[$uid[0]]) && isset($this->bo->resources[$uid[0]]['icon']))
|
||||
{
|
||||
$icons[$uid{0}] = html::image($this->bo->resources[$uid{0}]['app'],
|
||||
($this->bo->resources[$uid{0}]['icon'] ? $this->bo->resources[$uid{0}]['icon'] : 'navbar'),
|
||||
lang($this->bo->resources[$uid{0}]['app']),
|
||||
$icons[$uid[0]] = html::image($this->bo->resources[$uid[0]]['app'],
|
||||
($this->bo->resources[$uid[0]]['icon'] ? $this->bo->resources[$uid[0]]['icon'] : 'navbar'),
|
||||
lang($this->bo->resources[$uid[0]]['app']),
|
||||
'width="16px" height="16px"');
|
||||
}
|
||||
}
|
||||
@ -475,7 +475,7 @@ class uical
|
||||
return html::a_href($content,'/index.php',$vars,' target="_blank" title="'.html::htmlspecialchars(lang('Add')).
|
||||
'" onclick="'.$this->popup('this.href','this.target').'; return false;"');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns javascript to open a popup window: window.open(...)
|
||||
*
|
||||
@ -487,7 +487,7 @@ class uical
|
||||
*/
|
||||
function popup($link,$target='_blank',$width=750,$height=410,$Link_confirm_abort='',$Link_confirm_text='')
|
||||
{
|
||||
//Handle Exception for Calandar
|
||||
//Handle Exception for Calandar
|
||||
if (($Link_confirm_abort) && ($Link_confirm_text))
|
||||
{
|
||||
$returnvalue = 'javascript:var check=confirm(\''.$Link_confirm_text.'\');';
|
||||
@ -495,21 +495,21 @@ class uical
|
||||
// open confirm =0kay
|
||||
$returnvalue .= 'egw_openWindowCentered2('.($link == 'this.href' ? $link : "'".$link."'").','.
|
||||
($target == 'this.target' ? $target : "'".$target."'").",$width,$height,'yes')";
|
||||
$returnvalue .= '}';
|
||||
$returnvalue .= '}';
|
||||
//open confirm =Abort
|
||||
$returnvalue .=' else {';
|
||||
$returnvalue .= 'egw_openWindowCentered2('.($Link_confirm_abort == 'this.href' ? $Link_confirm_abort : "'".$Link_confirm_abort."'").','.
|
||||
($target == 'this.target' ? $target : "'".$target."'").",$width,$height,'yes')";
|
||||
$returnvalue .= '}';
|
||||
|
||||
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
|
||||
|
||||
return 'egw_openWindowCentered2('.($link == 'this.href' ? $link : "'".$link."'").','.
|
||||
($target == 'this.target' ? $target : "'".$target."'").",$width,$height,'yes')";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -631,7 +631,7 @@ class uical
|
||||
'week' => 'calendar.uiviews.week',
|
||||
'month' => 'calendar.uiviews.month') as $view => $menuaction)
|
||||
{
|
||||
if ($this->view == 'planner' || $this->view == 'listview')
|
||||
if ($this->view == 'planner' || $this->view == 'listview')
|
||||
{
|
||||
switch($view)
|
||||
{
|
||||
@ -743,12 +743,12 @@ function load_cal(url,id) {
|
||||
)),
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
$appname = 'calendar';
|
||||
$menu_title = lang('Calendar Menu');
|
||||
display_sidebox($appname,$menu_title,$file);
|
||||
|
||||
|
||||
// resources menu hooks
|
||||
foreach ($this->bo->resources as $resource)
|
||||
{
|
||||
|
@ -123,16 +123,16 @@ class uiforms extends uical
|
||||
{
|
||||
$participants[$uid] = $participant_types['u'][$uid] = $uid == $this->user ? 'A' : 'U';
|
||||
}
|
||||
elseif (is_array($this->bo->resources[$uid{0}]))
|
||||
elseif (is_array($this->bo->resources[$uid[0]]))
|
||||
{
|
||||
$res_data = $this->bo->resources[$uid{0}];
|
||||
$res_data = $this->bo->resources[$uid[0]];
|
||||
list($id,$quantity) = explode(':',substr($uid,1));
|
||||
$participants[$uid] = $participant_types[$uid{0}][$id] = ($res_data['new_status'] ? ExecMethod($res_data['new_status'],$id) : 'U').
|
||||
$participants[$uid] = $participant_types[$uid[0]][$id] = ($res_data['new_status'] ? ExecMethod($res_data['new_status'],$id) : 'U').
|
||||
((int) $quantity > 1 ? (int)$quantity : '');
|
||||
// if new_status == 'x', resource is not bookable
|
||||
if(strpos($participant_types[$uid{0}][$id],'x') !== false)
|
||||
if(strpos($participant_types[$uid[0]][$id],'x') !== false)
|
||||
{
|
||||
unset($participant_types[$uid{0}][$id]);
|
||||
unset($participant_types[$uid[0]][$id]);
|
||||
unset($participants[$uid]);
|
||||
}
|
||||
}
|
||||
@ -235,18 +235,40 @@ class uiforms extends uical
|
||||
{
|
||||
switch($key)
|
||||
{
|
||||
case 'add':
|
||||
if (!$content['participants']['account'] && !$content['participants']['resource'])
|
||||
{
|
||||
$msg = lang('You need to select an account, contact or resource first!');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete': // handled in default
|
||||
case 'quantity': // handled in new_resource
|
||||
case 'cal_resources':
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
// email or rfc822 addresse (eg. "Ralf Becker <ralf@domain.com>") in the search field
|
||||
// ToDo: get eTemplate to return that field
|
||||
if (($email = $_POST['exec']['participants']['resource']['query']) &&
|
||||
(preg_match('/^(.*<)?([a-z0-9_.@-]{8,})>?$/i',$email,$matches)))
|
||||
{
|
||||
// check if email belongs to account or contact --> prefer them over just emails
|
||||
if (($data = $GLOBALS['egw']->accounts->name2id($matches[2],'account_email')))
|
||||
{
|
||||
$event['participants'][$data] = $event['participant_types']['u'][$data] = 'U';
|
||||
}
|
||||
elseif ((list($data) = ExecMethod2('addressbook.bocontacts.search',array(
|
||||
'email' => $matches[2],
|
||||
'email_home' => $matches[2],
|
||||
),true,'','','',false,'OR')))
|
||||
{
|
||||
$event['participants']['c'.$data['id']] = $event['participant_types']['c'][$data['id']] = 'U';
|
||||
}
|
||||
else
|
||||
{
|
||||
$event['participants']['e'.$email] = $event['participant_types']['e'][$email] = 'U';
|
||||
}
|
||||
}
|
||||
elseif (!$content['participants']['account'] && !$content['participants']['resource'])
|
||||
{
|
||||
$msg = lang('You need to select an account, contact or resource first!');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'resource':
|
||||
list($app,$id) = explode(':',$data);
|
||||
foreach($this->bo->resources as $type => $data) if ($data['app'] == $app) break;
|
||||
@ -288,7 +310,7 @@ class uiforms extends uical
|
||||
else
|
||||
{
|
||||
$id = substr($uid,1);
|
||||
$type = $uid{0};
|
||||
$type = $uid[0];
|
||||
}
|
||||
if ($data['old_status'] != $status)
|
||||
{
|
||||
@ -563,6 +585,7 @@ class uiforms extends uical
|
||||
function custom_mail($event,$added)
|
||||
{
|
||||
$to = array();
|
||||
|
||||
foreach($event['participants'] as $uid => $status)
|
||||
{
|
||||
if ($status == 'R' || $uid == $this->user) continue;
|
||||
@ -586,17 +609,9 @@ class uiforms extends uical
|
||||
$to[] = $firstname.' '.$lastname.' <'.$email.'>';
|
||||
}
|
||||
}
|
||||
elseif ($uid{0} == 'c' )
|
||||
elseif(($info = $this->bo->resource_info($uid)))
|
||||
{
|
||||
if (!is_object($GLOBALS['egw']->contacts))
|
||||
{
|
||||
require_once(EGW_API_INC.'/class.contacts.inc.php');
|
||||
$GLOBALS['egw']->contacts = new contacts();
|
||||
}
|
||||
if (($contact = $GLOBALS['egw']->contacts->read(substr($uid,1))) && ($contact['email'] || $contact['email_home']))
|
||||
{
|
||||
$to[] = $contact['n_fn'].' <'.($contact['email']?$contact['email']:$contact['email_home']).'>';
|
||||
}
|
||||
$to[] = $info['email'];
|
||||
}
|
||||
}
|
||||
list($subject,$body) = $this->bo->get_update_message($event,$added ? MSG_ADDED : MSG_MODIFIED); // update-message is in TZ of the user
|
||||
@ -767,16 +782,26 @@ class uiforms extends uical
|
||||
$preserv['participants'][$row] = $content['participants'][$row] = array(
|
||||
'app' => $name == 'accounts' ? ($GLOBALS['egw']->accounts->get_type($id) == 'g' ? 'Group' : 'User') : $name,
|
||||
'uid' => $uid,
|
||||
'status' => $status{0},
|
||||
'old_status' => $status{0},
|
||||
'status' => $status[0],
|
||||
'old_status' => $status[0],
|
||||
'quantity' => substr($status,1),
|
||||
);
|
||||
$readonlys[$row.'[quantity]'] = $type == 'u' || !isset($this->bo->resources[$type]['max_quantity']);
|
||||
$readonlys[$row.'[status]'] = $readonlys[$row.'[status_recurrence]'] = !$this->bo->check_status_perms($uid,$event);
|
||||
$readonlys["delete[$uid]"] = !$this->bo->check_perms(EGW_ACL_EDIT,$event);
|
||||
$content['participants'][$row++]['title'] = $name == 'accounts' ?
|
||||
$GLOBALS['egw']->common->grab_owner_name($id) : egw_link::title($name,$id);
|
||||
|
||||
// todo: make the participants available as links with email as title
|
||||
if ($name == 'accounts')
|
||||
{
|
||||
$content['participants'][$row++]['title'] = $GLOBALS['egw']->common->grab_owner_name($id);
|
||||
}
|
||||
elseif (($info = $this->bo->resource_info($uid)))
|
||||
{
|
||||
$content['participants'][$row++]['title'] = $info['name'] ? $info['name'] : $info['email'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$content['participants'][$row++]['title'] = '#'.$uid;
|
||||
}
|
||||
// enumerate group-invitations, so people can accept/reject them
|
||||
if ($name == 'accounts' && $GLOBALS['egw']->accounts->get_type($id) == 'g' &&
|
||||
($members = $GLOBALS['egw']->accounts->members($id,true)))
|
||||
|
@ -12,7 +12,7 @@
|
||||
/* $Id$ */
|
||||
|
||||
$setup_info['calendar']['name'] = 'calendar';
|
||||
$setup_info['calendar']['version'] = '1.5.001';
|
||||
$setup_info['calendar']['version'] = '1.5.002';
|
||||
$setup_info['calendar']['app_order'] = 3;
|
||||
$setup_info['calendar']['enable'] = 1;
|
||||
|
||||
@ -80,3 +80,4 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -67,10 +67,10 @@
|
||||
),
|
||||
'egw_cal_user' => array(
|
||||
'fd' => array(
|
||||
'cal_id' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'),
|
||||
'cal_id' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'cal_recur_date' => array('type' => 'int','precision' => '8','default' => '0'),
|
||||
'cal_user_type' => array('type' => 'varchar','precision' => '1','nullable' => False,'default' => 'u'),
|
||||
'cal_user_id' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'),
|
||||
'cal_user_id' => array('type' => 'varchar','precision' => '128','nullable' => False),
|
||||
'cal_status' => array('type' => 'char','precision' => '1','default' => 'A'),
|
||||
'cal_quantity' => array('type' => 'int','precision' => '4','default' => '1')
|
||||
),
|
||||
|
@ -1599,4 +1599,22 @@
|
||||
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.5.001';
|
||||
}
|
||||
|
||||
|
||||
$test[] = '1.5.001';
|
||||
function calendar_upgrade1_5_001()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->AlterColumn('egw_cal_user','cal_id',array(
|
||||
'type' => 'int',
|
||||
'precision' => '4',
|
||||
'nullable' => False
|
||||
));
|
||||
$GLOBALS['egw_setup']->oProc->AlterColumn('egw_cal_user','cal_user_id',array(
|
||||
'type' => 'varchar',
|
||||
'precision' => '128',
|
||||
'nullable' => False
|
||||
));
|
||||
|
||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.5.002';
|
||||
}
|
||||
?>
|
||||
|
Loading…
Reference in New Issue
Block a user