- fixed serveral bugs in the conflict checking for resources (with quantity)

- centralized all calls for resource-infos into new method bocal::resource_info, which also caches the data, as the resource app always queries DB
- bocal::search() returns now false, if you have no rights to any of the given users
This commit is contained in:
Ralf Becker 2006-03-05 10:26:03 +00:00
parent df5999e2da
commit 0497afc3df
2 changed files with 51 additions and 34 deletions

View File

@ -246,7 +246,8 @@ class bocal
* show_rejected if set rejected invitation are shown only when true, otherwise it depends on the cal-pref or a running query * 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 * 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' * 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) function &search($params)
{ {
@ -276,6 +277,9 @@ class bocal
{ {
continue; // for non-groups (eg. users), we stop here if we have no read-rights continue; // for non-groups (eg. users), we stop here if we have no read-rights
} }
// the further code is only for real users
if (!is_numeric($user)) continue;
// for groups we have to include the members // for groups we have to include the members
if ($GLOBALS['egw']->accounts->get_type($user) == 'g') if ($GLOBALS['egw']->accounts->get_type($user) == 'g')
{ {
@ -312,7 +316,7 @@ class bocal
// as calling the so-layer without users would give the events of all users (!) // as calling the so-layer without users would give the events of all users (!)
if (!count($users)) if (!count($users))
{ {
return array(); return false;
} }
if (isset($params['start'])) $start = $this->date2ts($params['start']); if (isset($params['start'])) $start = $this->date2ts($params['start']);
@ -833,6 +837,29 @@ class bocal
} }
} }
/**
* Fetch information about a resource
*
* We do some caching here, as the resource itself might not do it.
*
* @param string $uid string with one-letter resource-type and numerical resource-id, eg. "r19"
* @return array/boolean array with keys res_id,cat_id,name,useable (name definied by max_quantity in $this->resources),rights,responsible or false if $uid is not found
*/
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 ($this->debug && ($this->debug > 2 || $this->debug == 'resource_info'))
{
$this->debug_message('bocal::resource_info(%1) = %2',True,$uid,$res_info_cache[$uid]);
}
return $res_info_cache[$uid];
}
/** /**
* Checks if the current user has the necessary ACL rights * Checks if the current user has the necessary ACL rights
* *
@ -852,9 +879,9 @@ class bocal
$event_in = $event; $event_in = $event;
if ($other && !is_numeric($other)) if ($other && !is_numeric($other))
{ {
$resource = ExecMethod($this->resources[$other{0}]['info'],substr($other,1)); $resource = $this->resource_info($other);
return $needed & $resource[0]['rights']; return $needed & $resource['rights'];
} }
if (is_int($event) && $event == 0) if (is_int($event) && $event == 0)
{ {
@ -902,8 +929,8 @@ class bocal
elseif (!is_numeric($uid)) elseif (!is_numeric($uid))
{ {
// if we have a resource as participant // if we have a resource as participant
$resource = ExecMethod($this->resources[$uid{0}]['info'],substr($uid,1)); $resource = $this->resource_info($uid);
$grants |= $resource[0]['rights']; $grants |= $resource['rights'];
} }
} }
} }
@ -1250,23 +1277,14 @@ class bocal
{ {
static $id2lid = array(); static $id2lid = array();
if ($use_type && $use_type != 'u') $id = $use_type.$id;
if (!isset($id2lid[$id])) if (!isset($id2lid[$id]))
{ {
if (!is_numeric($id) || $use_type && $use_type != 'u') if (!is_numeric($id))
{ {
$type = $use_type ? $use_type : $id[0]; $res_info = $this->resource_info($id);
$res_id = $use_type ? $id : (int) substr($id,1); $id2lid[$id] = $res_info && isset($res_info['name']) ? $res_info['name'] : "resource($id)";
if (isset($this->resources[$type]) && isset($this->resources[$type]['info']))
{
list($data) = ExecMethod($this->resources[$type]['info'],$res_id);
//echo "$type$res_id: "; _debug_array($data);
$id2lid[$id] = $data['name'];
}
else
{
$id2lid[$id] = "resource($id)";
}
} }
else else
{ {

View File

@ -126,7 +126,7 @@ class bocalupdate extends bocal
$types_with_quantity = array(); $types_with_quantity = array();
foreach($this->resources as $type => $data) foreach($this->resources as $type => $data)
{ {
if ($data['use_quantity']) $types_with_quantity[] = $type; if ($data['max_quantity']) $types_with_quantity[] = $type;
} }
// get all NOT rejected participants and evtl. their quantity // get all NOT rejected participants and evtl. their quantity
$quantity = $users = array(); $quantity = $users = array();
@ -135,9 +135,9 @@ class bocalupdate extends bocal
if ($status[0] == 'R') continue; // ignore rejected participants if ($status[0] == 'R') continue; // ignore rejected participants
$users[] = $uid; $users[] = $uid;
if (in_array($uid[0],$types_with_quantity)) if (in_array($uid{0},$types_with_quantity))
{ {
$quantity[$uid] = min(1,(int) substr($overlap['participants']['uid'],2)); $quantity[$uid] = max(1,(int) substr($status,2));
} }
} }
$overlapping_events =& $this->search(array( $overlapping_events =& $this->search(array(
@ -167,26 +167,25 @@ 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 = ExecMethod($this->resources[$uid[0]]['info']); $res_info = $this->resource_info($uid);
$max_quantity[$uid] = $res_info[$this->resources[$uid[0]]['use_quantity']]; $max_quantity[$uid] = $res_info[$this->resources[$uid{0}]['max_quantity']];
} }
$quantity[$uid] += min(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)
{ {
$possible_quantity_conflicts[$uid][] =& $overlapping_events[$k]; // an other event can give the conflict $possible_quantity_conflicts[$uid][] =& $overlapping_events[$k]; // an other event can give the conflict
unset($common_parts[$uid]); unset($common_parts[$n]);
continue; continue;
} }
// now we have a quantity conflict for $uid // now we have a quantity conflict for $uid
@ -205,9 +204,9 @@ class bocalupdate extends bocal
{ {
if ($quantity[$uid] > $max) if ($quantity[$uid] > $max)
{ {
foreach($possible_quantity_conflicts[$uid] as $conflict) foreach((array)$possible_quantity_conflicts[$uid] as $conflict)
{ {
$conflicts[$conflict['id'].'-'.$this->bo->date2ts($conflict['start'])] =& $possible_quantity_conflicts[$k]; $conflicts[$conflict['id'].'-'.$this->date2ts($conflict['start'])] =& $possible_quantity_conflicts[$k];
} }
} }
} }
@ -233,7 +232,7 @@ class bocalupdate extends bocal
$this->debug_message('bocalupdate::update() %1 conflicts found %2',false,count($conflicts),$conflicts); $this->debug_message('bocalupdate::update() %1 conflicts found %2',false,count($conflicts),$conflicts);
} }
return $conflicts; return $conflicts;
} }
} }
// save the event to the database // save the event to the database
if ($touch_modified) if ($touch_modified)