limit groupVCard to contacts of same addressbook, as OS X and iOS only allows that and PUTs would remove contacts from other ABs, also fixed not working multiget report of lists/groups

This commit is contained in:
Ralf Becker 2012-02-01 00:31:24 +00:00
parent b8d9b748ac
commit f5cb740795
4 changed files with 27 additions and 13 deletions

View File

@ -207,7 +207,15 @@ class addressbook_groupdav extends groupdav_handler
// add groups after contacts // add groups after contacts
if (!$start || count($contacts) < $start[1]) if (!$start || count($contacts) < $start[1])
{ {
if (($lists = $this->bo->read_lists(array('list_owner' => isset($filter['contact_owner'])?$filter['contact_owner']:array_keys($this->bo->grants))))) $where = array(
'list_owner' => isset($filter['contact_owner'])?$filter['contact_owner']:array_keys($this->bo->grants)
);
if (isset($filter[self::$path_attr])) // multiget report?
{
$where['list_'.self::$path_attr] = $filter[self::$path_attr];
}
//error_log(__METHOD__."() filter=".array2string($filter).', where='.array2string($where));
if (($lists = $this->bo->read_lists($where,'contact_uid',true))) // true = limit to contacts in same AB!
{ {
//_debug_array($lists); //_debug_array($lists);
foreach($lists as $list) foreach($lists as $list)
@ -761,11 +769,13 @@ class addressbook_groupdav extends groupdav_handler
$contact = $this->bo->read(array(self::$path_attr => $id, 'tid' => $non_deleted_tids)); $contact = $this->bo->read(array(self::$path_attr => $id, 'tid' => $non_deleted_tids));
// see if we have a distribution-list / group with that id // see if we have a distribution-list / group with that id
if (!$contact && ($contact = $this->bo->read_lists(array('list_'.self::$path_attr => $id)))) // bo->read_list(..., true) limits returned uid to same owner's addressbook, as iOS and OS X addressbooks
// only understands/shows that and if return more, save_lists would delete the others ones on update!
if (!$contact && ($contact = $this->bo->read_lists(array('list_'.self::$path_attr => $id),'contact_uid',true)))
{ {
$contact = array_shift($contact); $contact = array_shift($contact);
$contact['n_fn'] = $contact['n_family'] = $contact['list_name']; $contact['n_fn'] = $contact['n_family'] = $contact['list_name'];
foreach(array('owner','id','carddav_name','modified','modifier','created','creator') as $name) foreach(array('owner','id','carddav_name','modified','modifier','created','creator','etag') as $name)
{ {
$contact[$name] = $contact['list_'.$name]; $contact[$name] = $contact['list_'.$name];
} }

View File

@ -965,13 +965,14 @@ class addressbook_so
* *
* @param array $keys column-name => value(s) pairs, eg. array('list_uid'=>$uid) * @param array $keys column-name => value(s) pairs, eg. array('list_uid'=>$uid)
* @param string $member_attr='contact_uid' null: no members, 'contact_uid', 'contact_id', 'caldav_name' return members as that attribute * @param string $member_attr='contact_uid' null: no members, 'contact_uid', 'contact_id', 'caldav_name' return members as that attribute
* @return array with list_id => array(list_id,list_name,list_owner,...,'members') pairs * @param boolean $limit_in_ab=false if true only return members from the same owners addressbook
* @return array with list_id => array(list_id,list_name,list_owner,...) pairs
*/ */
function read_lists(array $keys,$member_attr='contact_uid') function read_lists($keys,$member_attr=null,$limit_in_ab=false)
{ {
if (!method_exists($this->somain,'get_lists')) return false; if (!method_exists($this->somain,'get_lists')) return false;
return $this->somain->get_lists($keys,null,$member_attr); return $this->somain->get_lists($keys,null,$member_attr,$limit_in_ab);
} }
/** /**
@ -1066,7 +1067,7 @@ class addressbook_so
*/ */
function lists_ctag($owner=null) function lists_ctag($owner=null)
{ {
if (!method_exists($this->somain,'read_list')) return 0; if (!method_exists($this->somain,'lists_ctag')) return 0;
return $this->somain->lists_ctag($owner); return $this->somain->lists_ctag($owner);
} }

View File

@ -462,27 +462,30 @@ class addressbook_sql extends so_sql_cf
* or whole where array: column-name => value(s) pairs * or whole where array: column-name => value(s) pairs
* @param string $uid_column='list_owner' column-name or null to use $uids as where array * @param string $uid_column='list_owner' column-name or null to use $uids as where array
* @param string $member_attr=null null: no members, 'contact_uid', 'contact_id', 'caldav_name' return members as that attribute * @param string $member_attr=null null: no members, 'contact_uid', 'contact_id', 'caldav_name' return members as that attribute
* @param boolean $limit_in_ab=false if true only return members from the same owners addressbook
* @return array with list_id => array(list_id,list_name,list_owner,...) pairs * @return array with list_id => array(list_id,list_name,list_owner,...) pairs
*/ */
function get_lists($uids,$uid_column='list_owner',$member_attr=null) function get_lists($uids,$uid_column='list_owner',$member_attr=null,$limit_in_ab=false)
{ {
$user = $GLOBALS['egw_info']['user']['account_id'];
$lists = array(); $lists = array();
foreach($this->db->select($this->lists_table,'*',$uid_column?array($uid_column=>$uids):$uids,__LINE__,__FILE__, foreach($this->db->select($this->lists_table,'*',$uid_column?array($uid_column=>$uids):$uids,__LINE__,__FILE__,
false,'ORDER BY list_owner<>'.(int)$GLOBALS['egw_info']['user']['account_id'].',list_name') as $row) false,'ORDER BY list_owner<>'.(int)$GLOBALS['egw_info']['user']['account_id'].',list_name') as $row)
{ {
if ($member_attr) $row['members'] = array();
$lists[$row['list_id']] = $row; $lists[$row['list_id']] = $row;
} }
if ($lists && $member_attr && in_array($member_attr,array('contact_id','contact_uid','caldav_name'))) if ($lists && $member_attr && in_array($member_attr,array('contact_id','contact_uid','caldav_name')))
{ {
foreach($this->db->select($this->ab2list_table,"list_id,$member_attr",array('list_id'=>array_keys($lists)), foreach($this->db->select($this->ab2list_table,"$this->ab2list_table.list_id,$this->table_name.$member_attr",
$this->db->expression($this->ab2list_table, $this->ab2list_table.'.', array('list_id'=>array_keys($lists))),
__LINE__,__FILE__,false,$member_attr=='contact_id' ? '' : __LINE__,__FILE__,false,$member_attr=='contact_id' ? '' :
'',false,0,"JOIN $this->table_name ON $this->ab2list_table.contact_id=$this->table_name.contact_id") as $row) '',false,0,"JOIN $this->table_name ON $this->ab2list_table.contact_id=$this->table_name.contact_id".
($limit_in_ab?" JOIN $this->lists_table ON $this->lists_table.list_id=$this->ab2list_table.list_id AND $this->lists_table.list_owner=$this->table_name.contact_owner":'')) as $row)
{ {
$lists[$row['list_id']]['members'][] = $row[$member_attr]; $lists[$row['list_id']]['members'][] = $row[$member_attr];
} }
} }
error_log(__METHOD__.'('.array2string($uids).", '$uid_column', '$member_attr') returning ".array2string($lists)); //error_log(__METHOD__.'('.array2string($uids).", '$uid_column', '$member_attr') returning ".array2string($lists));
return $lists; return $lists;
} }

View File

@ -1050,7 +1050,7 @@ class addressbook_vcal extends addressbook_bo
$vCard->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Addressbook '.$GLOBALS['egw_info']['apps']['addressbook']['version'].'//'. $vCard->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Addressbook '.$GLOBALS['egw_info']['apps']['addressbook']['version'].'//'.
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang'])); strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
$vCard->setAttribute('N',$list['list_name']); $vCard->setAttribute('N',$list['list_name'],array(),true,array($list['list_name'],'','','',''));
$vCard->setAttribute('FN',$list['list_name']); $vCard->setAttribute('FN',$list['list_name']);
$vCard->setAttribute('X-ADDRESSBOOKSERVER-KIND','group'); $vCard->setAttribute('X-ADDRESSBOOKSERVER-KIND','group');