mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-29 11:23: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
@ -185,6 +185,11 @@ class bocal
|
|||||||
$this->resources[$data['type']] = $data + array('app' => $app);
|
$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);
|
$GLOBALS['egw']->session->appsession('resources','calendar',$this->resources);
|
||||||
}
|
}
|
||||||
//echo "registered resources="; _debug_array($this->resources);
|
//echo "registered resources="; _debug_array($this->resources);
|
||||||
@ -192,6 +197,37 @@ class bocal
|
|||||||
$this->config = config::read('calendar');
|
$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'
|
* Add group-members as participants with status 'G'
|
||||||
*
|
*
|
||||||
@ -882,7 +918,29 @@ class bocal
|
|||||||
|
|
||||||
if (!isset($res_info_cache[$uid]))
|
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'))
|
if ($this->debug && ($this->debug > 2 || $this->debug == 'resource_info'))
|
||||||
{
|
{
|
||||||
@ -1249,7 +1307,7 @@ class bocal
|
|||||||
|
|
||||||
if ($display_day)
|
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)
|
for ($i = 0; $i < 5; $i += 2)
|
||||||
{
|
{
|
||||||
@ -1364,7 +1422,11 @@ class bocal
|
|||||||
{
|
{
|
||||||
if (!is_numeric($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
|
else
|
||||||
{
|
{
|
||||||
@ -1755,7 +1817,7 @@ class bocal
|
|||||||
{
|
{
|
||||||
if (is_numeric($user)) $user = $GLOBALS['egw']->accounts->id2name($user);
|
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'] : '').
|
($_SERVER['HTTPS'] ? 'https://' : 'http://').$_SERVER['HTTP_HOST'] : '').
|
||||||
$GLOBALS['egw_info']['server']['webserver_url'].'/calendar/freebusy.php?user='.urlencode($user).
|
$GLOBALS['egw_info']['server']['webserver_url'].'/calendar/freebusy.php?user='.urlencode($user).
|
||||||
($pw ? '&password='.urlencode($pw) : '');
|
($pw ? '&password='.urlencode($pw) : '');
|
||||||
|
@ -155,7 +155,7 @@ class bocalupdate extends bocal
|
|||||||
$users = array_unique($users);
|
$users = array_unique($users);
|
||||||
}
|
}
|
||||||
$users[] = $uid;
|
$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));
|
$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']));
|
$common_parts = array_intersect($users,array_keys($overlap['participants']));
|
||||||
foreach($common_parts as $n => $uid)
|
foreach($common_parts as $n => $uid)
|
||||||
{
|
{
|
||||||
if ($overlap['participants'][$uid]{0} == 'R')
|
if ($overlap['participants'][$uid][0] == 'R')
|
||||||
{
|
{
|
||||||
unset($common_parts[$uid]);
|
unset($common_parts[$uid]);
|
||||||
continue;
|
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
|
continue; // no quantity check: quantity allways 1 ==> conflict
|
||||||
}
|
}
|
||||||
if (!isset($max_quantity[$uid]))
|
if (!isset($max_quantity[$uid]))
|
||||||
{
|
{
|
||||||
$res_info = $this->resource_info($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));
|
$quantity[$uid] += max(1,(int) substr($overlap['participants'][$uid],2));
|
||||||
if ($quantity[$uid] <= $max_quantity[$uid])
|
if ($quantity[$uid] <= $max_quantity[$uid])
|
||||||
@ -741,7 +741,7 @@ class bocalupdate extends bocal
|
|||||||
*/
|
*/
|
||||||
function check_status_perms($uid,$event)
|
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;
|
if (!is_array($event) && !($event = $this->read($event))) return false;
|
||||||
|
|
||||||
@ -774,7 +774,7 @@ class bocalupdate extends bocal
|
|||||||
{
|
{
|
||||||
return false;
|
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());
|
$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
|
$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';
|
$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 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://').
|
$link = ($GLOBALS['egw_info']['server']['enforce_ssl'] || $_SERVER['HTTPS'] ? 'https://' : 'http://').
|
||||||
($GLOBALS['egw_info']['server']['hostname'] ? $GLOBALS['egw_info']['server']['hostname'] : $_SERVER['HTTP_HOST']).
|
($GLOBALS['egw_info']['server']['hostname'] ? $GLOBALS['egw_info']['server']['hostname'] : $_SERVER['HTTP_HOST']).
|
||||||
|
@ -191,14 +191,9 @@
|
|||||||
case 'ATTENDEE':
|
case 'ATTENDEE':
|
||||||
foreach((array)$event['participants'] as $uid => $status)
|
foreach((array)$event['participants'] as $uid => $status)
|
||||||
{
|
{
|
||||||
// ToDo, this needs to deal with resources too!!!
|
if (!($info = $this->resource_info($uid))) continue;
|
||||||
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'));
|
|
||||||
// RB: MAILTO href contains only the email-address, NO cn!
|
// 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={CHAIR|REQ-PARTICIPANT|OPT-PARTICIPANT|NON-PARTICIPANT} NOT used by eGW atm.
|
||||||
$role = $uid == $event['owner'] ? 'CHAIR' : 'REQ-PARTICIPANT';
|
$role = $uid == $event['owner'] ? 'CHAIR' : 'REQ-PARTICIPANT';
|
||||||
// RSVP={TRUE|FALSE} // resonse expected, not set in eGW => status=U
|
// 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.
|
// PARTSTAT={NEEDS-ACTION|ACCEPTED|DECLINED|TENTATIVE|DELEGATED|COMPLETED|IN-PROGRESS} everything from delegated is NOT used by eGW atm.
|
||||||
$status = $this->status_egw2ical[$status];
|
$status = $this->status_egw2ical[$status];
|
||||||
// CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN}
|
// CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN}
|
||||||
switch (is_numeric($uid) ? $GLOBALS['egw']->accounts->get_type($uid) : $uid{0})
|
switch ($info['type'])
|
||||||
{
|
{
|
||||||
case 'g':
|
case 'g':
|
||||||
$cutype = 'GROUP';
|
$cutype = 'GROUP';
|
||||||
@ -214,21 +209,22 @@
|
|||||||
case 'r':
|
case 'r':
|
||||||
$cutype = 'RESOURCE';
|
$cutype = 'RESOURCE';
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u': // account
|
||||||
|
case 'c': // contact
|
||||||
|
case 'e': // email address
|
||||||
$cutype = 'INDIVIDUAL';
|
$cutype = 'INDIVIDUAL';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$cutype = 'UNKNOWN';
|
$cutype = 'UNKNOWN';
|
||||||
$cutype = 'INDIVIDUAL';
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
$parameters['ATTENDEE'][] = array(
|
$parameters['ATTENDEE'][] = array(
|
||||||
'CN' => $cn,
|
'CN' => $info['name'],
|
||||||
'ROLE' => $role,
|
'ROLE' => $role,
|
||||||
'PARTSTAT' => $status,
|
'PARTSTAT' => $status,
|
||||||
'CUTYPE' => $cutype,
|
'CUTYPE' => $cutype,
|
||||||
'RSVP' => $rsvp,
|
'RSVP' => $rsvp,
|
||||||
);
|
)+($info['type'] != 'e' ? array('X-EGROUPWARE-UID' => $uid) : array());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -563,7 +559,7 @@
|
|||||||
break;
|
break;
|
||||||
case 'RRULE':
|
case 'RRULE':
|
||||||
$recurence = $attributes['value'];
|
$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
|
// vCard 2.0 values for all types
|
||||||
if (preg_match('/UNTIL=([0-9T]+)/',$recurence,$matches))
|
if (preg_match('/UNTIL=([0-9T]+)/',$recurence,$matches))
|
||||||
{
|
{
|
||||||
@ -768,28 +764,46 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ATTENDEE':
|
case 'ATTENDEE':
|
||||||
if (preg_match('/MAILTO:([@.a-z0-9_-]+)/i',$attributes['value'],$matches) &&
|
if (preg_match('/MAILTO:([@.a-z0-9_-]+)/i',$attributes['value'],$matches) ||
|
||||||
($uid = $GLOBALS['egw']->accounts->name2id($matches[1],'account_email')))
|
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'])] :
|
$this->status_ical2egw[strtoupper($attributes['params']['PARTSTAT'])] :
|
||||||
($uid == $event['owner'] ? 'A' : 'U');
|
($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;
|
break;
|
||||||
case 'ORGANIZER': // will be written direct to the event
|
case 'ORGANIZER': // will be written direct to the event
|
||||||
if (preg_match('/MAILTO:([@.a-z0-9_-]+)/i',$attributes['value'],$matches) &&
|
if (preg_match('/MAILTO:([@.a-z0-9_-]+)/i',$attributes['value'],$matches) &&
|
||||||
@ -1195,7 +1209,7 @@
|
|||||||
break;
|
break;
|
||||||
case 'RRULE':
|
case 'RRULE':
|
||||||
$recurence = $attributes['value'];
|
$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
|
// vCard 2.0 values for all types
|
||||||
if (preg_match('/UNTIL=([0-9T]+)/',$recurence,$matches))
|
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)
|
* combines user_type and user_id into a single string or integer (for users)
|
||||||
*
|
*
|
||||||
* @param string $user_type 1-char type: 'u' = user, ...
|
* @param string $user_type 1-char type: 'u' = user, ...
|
||||||
* @param int $user_id id
|
* @param string|int $user_id id
|
||||||
* @return string/int combined id
|
* @return string|int combined id
|
||||||
*/
|
*/
|
||||||
function combine_user($user_type,$user_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
|
* splits the combined user_type and user_id into a single values
|
||||||
*
|
*
|
||||||
* @param string $user_type 1-char type: 'u' = user, ...
|
* @param string|int $uid
|
||||||
* @param int $user_id id
|
* @param string &$user_type 1-char type: 'u' = user, ...
|
||||||
* @return string/int
|
* @param string|int &$user_id id
|
||||||
*/
|
*/
|
||||||
function split_user($uid,&$user_type,&$user_id)
|
function split_user($uid,&$user_type,&$user_id)
|
||||||
{
|
{
|
||||||
@ -719,7 +719,7 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$user_type = $uid[0];
|
$user_type = $uid[0];
|
||||||
$user_id = (int) substr($uid,1);
|
$user_id = substr($uid,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,11 +282,11 @@ class uical
|
|||||||
}
|
}
|
||||||
else // change only the owners of the given type
|
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);
|
$owners = explode(',',$states['owner'] ? $states['owner'] : $default);
|
||||||
foreach($owners as $key => $owner)
|
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]);
|
unset($owners[$key]);
|
||||||
}
|
}
|
||||||
@ -390,7 +390,7 @@ class uical
|
|||||||
// icons for single user, multiple users or group(s) and resources
|
// icons for single user, multiple users or group(s) and resources
|
||||||
foreach($event['participants'] as $uid => $status)
|
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')
|
if (isset($icons['single']) || $GLOBALS['egw']->accounts->get_type($uid) == 'g')
|
||||||
{
|
{
|
||||||
@ -402,11 +402,11 @@ class uical
|
|||||||
$icons['single'] = html::image('calendar','single');
|
$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'],
|
$icons[$uid[0]] = html::image($this->bo->resources[$uid[0]]['app'],
|
||||||
($this->bo->resources[$uid{0}]['icon'] ? $this->bo->resources[$uid{0}]['icon'] : 'navbar'),
|
($this->bo->resources[$uid[0]]['icon'] ? $this->bo->resources[$uid[0]]['icon'] : 'navbar'),
|
||||||
lang($this->bo->resources[$uid{0}]['app']),
|
lang($this->bo->resources[$uid[0]]['app']),
|
||||||
'width="16px" height="16px"');
|
'width="16px" height="16px"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,16 +123,16 @@ class uiforms extends uical
|
|||||||
{
|
{
|
||||||
$participants[$uid] = $participant_types['u'][$uid] = $uid == $this->user ? 'A' : 'U';
|
$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));
|
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 : '');
|
((int) $quantity > 1 ? (int)$quantity : '');
|
||||||
// if new_status == 'x', resource is not bookable
|
// 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]);
|
unset($participants[$uid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,18 +235,40 @@ class uiforms extends uical
|
|||||||
{
|
{
|
||||||
switch($key)
|
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 'delete': // handled in default
|
||||||
case 'quantity': // handled in new_resource
|
case 'quantity': // handled in new_resource
|
||||||
case 'cal_resources':
|
case 'cal_resources':
|
||||||
break;
|
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':
|
case 'resource':
|
||||||
list($app,$id) = explode(':',$data);
|
list($app,$id) = explode(':',$data);
|
||||||
foreach($this->bo->resources as $type => $data) if ($data['app'] == $app) break;
|
foreach($this->bo->resources as $type => $data) if ($data['app'] == $app) break;
|
||||||
@ -288,7 +310,7 @@ class uiforms extends uical
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$id = substr($uid,1);
|
$id = substr($uid,1);
|
||||||
$type = $uid{0};
|
$type = $uid[0];
|
||||||
}
|
}
|
||||||
if ($data['old_status'] != $status)
|
if ($data['old_status'] != $status)
|
||||||
{
|
{
|
||||||
@ -563,6 +585,7 @@ class uiforms extends uical
|
|||||||
function custom_mail($event,$added)
|
function custom_mail($event,$added)
|
||||||
{
|
{
|
||||||
$to = array();
|
$to = array();
|
||||||
|
|
||||||
foreach($event['participants'] as $uid => $status)
|
foreach($event['participants'] as $uid => $status)
|
||||||
{
|
{
|
||||||
if ($status == 'R' || $uid == $this->user) continue;
|
if ($status == 'R' || $uid == $this->user) continue;
|
||||||
@ -586,17 +609,9 @@ class uiforms extends uical
|
|||||||
$to[] = $firstname.' '.$lastname.' <'.$email.'>';
|
$to[] = $firstname.' '.$lastname.' <'.$email.'>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif ($uid{0} == 'c' )
|
elseif(($info = $this->bo->resource_info($uid)))
|
||||||
{
|
{
|
||||||
if (!is_object($GLOBALS['egw']->contacts))
|
$to[] = $info['email'];
|
||||||
{
|
|
||||||
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']).'>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list($subject,$body) = $this->bo->get_update_message($event,$added ? MSG_ADDED : MSG_MODIFIED); // update-message is in TZ of the user
|
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(
|
$preserv['participants'][$row] = $content['participants'][$row] = array(
|
||||||
'app' => $name == 'accounts' ? ($GLOBALS['egw']->accounts->get_type($id) == 'g' ? 'Group' : 'User') : $name,
|
'app' => $name == 'accounts' ? ($GLOBALS['egw']->accounts->get_type($id) == 'g' ? 'Group' : 'User') : $name,
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
'status' => $status{0},
|
'status' => $status[0],
|
||||||
'old_status' => $status{0},
|
'old_status' => $status[0],
|
||||||
'quantity' => substr($status,1),
|
'quantity' => substr($status,1),
|
||||||
);
|
);
|
||||||
$readonlys[$row.'[quantity]'] = $type == 'u' || !isset($this->bo->resources[$type]['max_quantity']);
|
$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[$row.'[status]'] = $readonlys[$row.'[status_recurrence]'] = !$this->bo->check_status_perms($uid,$event);
|
||||||
$readonlys["delete[$uid]"] = !$this->bo->check_perms(EGW_ACL_EDIT,$event);
|
$readonlys["delete[$uid]"] = !$this->bo->check_perms(EGW_ACL_EDIT,$event);
|
||||||
$content['participants'][$row++]['title'] = $name == 'accounts' ?
|
// todo: make the participants available as links with email as title
|
||||||
$GLOBALS['egw']->common->grab_owner_name($id) : egw_link::title($name,$id);
|
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
|
// enumerate group-invitations, so people can accept/reject them
|
||||||
if ($name == 'accounts' && $GLOBALS['egw']->accounts->get_type($id) == 'g' &&
|
if ($name == 'accounts' && $GLOBALS['egw']->accounts->get_type($id) == 'g' &&
|
||||||
($members = $GLOBALS['egw']->accounts->members($id,true)))
|
($members = $GLOBALS['egw']->accounts->members($id,true)))
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
$setup_info['calendar']['name'] = 'calendar';
|
$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']['app_order'] = 3;
|
||||||
$setup_info['calendar']['enable'] = 1;
|
$setup_info['calendar']['enable'] = 1;
|
||||||
|
|
||||||
@ -80,3 +80,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,10 +67,10 @@
|
|||||||
),
|
),
|
||||||
'egw_cal_user' => array(
|
'egw_cal_user' => array(
|
||||||
'fd' => 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_recur_date' => array('type' => 'int','precision' => '8','default' => '0'),
|
||||||
'cal_user_type' => array('type' => 'varchar','precision' => '1','nullable' => False,'default' => 'u'),
|
'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_status' => array('type' => 'char','precision' => '1','default' => 'A'),
|
||||||
'cal_quantity' => array('type' => 'int','precision' => '4','default' => '1')
|
'cal_quantity' => array('type' => 'int','precision' => '4','default' => '1')
|
||||||
),
|
),
|
||||||
|
@ -1599,4 +1599,22 @@
|
|||||||
|
|
||||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.5.001';
|
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