mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-01 12:23:50 +01:00
Fix GroupDAV entry duplication issue
This commit is contained in:
parent
796beca7b1
commit
8175306dea
@ -132,7 +132,6 @@ class addressbook_groupdav extends groupdav_handler
|
|||||||
$handler = self::_get_handler();
|
$handler = self::_get_handler();
|
||||||
}
|
}
|
||||||
unset($filter['address_data']);
|
unset($filter['address_data']);
|
||||||
|
|
||||||
$files = array();
|
$files = array();
|
||||||
// we query etag and modified, as LDAP does not have the strong sql etag
|
// we query etag and modified, as LDAP does not have the strong sql etag
|
||||||
if (($contacts =& $this->bo->search(array(),$address_data ? false : array('id','uid','etag','modified'),'contact_id','','',False,'AND',$start,$filter)))
|
if (($contacts =& $this->bo->search(array(),$address_data ? false : array('id','uid','etag','modified'),'contact_id','','',False,'AND',$start,$filter)))
|
||||||
@ -147,7 +146,7 @@ class addressbook_groupdav extends groupdav_handler
|
|||||||
);
|
);
|
||||||
if ($address_data)
|
if ($address_data)
|
||||||
{
|
{
|
||||||
$content = $handler->getVCard($contact,$this->charset,false);
|
$content = $handler->getVCard($contact['id'],$this->charset,false);
|
||||||
$props[] = HTTP_WebDAV_Server::mkprop('getcontentlength',bytes($content));
|
$props[] = HTTP_WebDAV_Server::mkprop('getcontentlength',bytes($content));
|
||||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'address-data',$content,true);
|
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'address-data',$content,true);
|
||||||
}
|
}
|
||||||
@ -269,35 +268,69 @@ class addressbook_groupdav extends groupdav_handler
|
|||||||
function put(&$options,$id,$user=null)
|
function put(&$options,$id,$user=null)
|
||||||
{
|
{
|
||||||
if ($this->debug) error_log(__METHOD__.'('.array2string($options).",$id,$user)");
|
if ($this->debug) error_log(__METHOD__.'('.array2string($options).",$id,$user)");
|
||||||
$ok = $this->_common_get_put_delete('PUT',$options,$id);
|
|
||||||
if (!is_null($ok) && !is_array($ok))
|
$oldContact = $this->_common_get_put_delete('PUT',$options,$id);
|
||||||
|
if (!is_null($oldContact) && !is_array($oldContact))
|
||||||
{
|
{
|
||||||
return $ok;
|
return $oldContact;
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler = self::_get_handler();
|
$handler = self::_get_handler();
|
||||||
$vCard = htmlspecialchars_decode($options['content']);
|
$vCard = htmlspecialchars_decode($options['content']);
|
||||||
$contactId = (is_array($ok) ? -1 : $ok['id']);
|
|
||||||
$contact = $handler->vcardtoegw($vCard, $contactId);
|
if (is_array($oldContact))
|
||||||
|
{
|
||||||
|
$contactId = $oldContact['id'];
|
||||||
|
$retval = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new entry?
|
||||||
|
if (($foundContacts = $handler->search($vCard)))
|
||||||
|
{
|
||||||
|
if (($contactId = array_shift($foundContacts)) &&
|
||||||
|
($oldContact = $this->bo->read($contactId)))
|
||||||
|
{
|
||||||
|
$retval = '301 Moved Permanently';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// to be safe
|
||||||
|
$contactId = -1;
|
||||||
|
$retval = '201 Created';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new entry
|
||||||
|
$contactId = -1;
|
||||||
|
$retval = '201 Created';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$contact = $handler->vcardtoegw($vCard);
|
||||||
|
|
||||||
if (is_array($contact['category']))
|
if (is_array($contact['category']))
|
||||||
{
|
{
|
||||||
$contact['category'] = implode(',',$this->bo->find_or_add_categories($contact['category'], $contactId));
|
$contact['category'] = implode(',',$this->bo->find_or_add_categories($contact['category'], $contactId));
|
||||||
}
|
}
|
||||||
elseif ($contactId > 0)
|
elseif ($contactId > 0)
|
||||||
{
|
{
|
||||||
$contact['category'] = $ok['category'];
|
$contact['category'] = $oldContact['category'];
|
||||||
}
|
}
|
||||||
if (!is_null($ok))
|
if (is_array($oldContact))
|
||||||
{
|
{
|
||||||
$contact['id'] = $ok['id'];
|
$contact['id'] = $oldContact['id'];
|
||||||
// dont allow the client to overwrite certain values
|
// dont allow the client to overwrite certain values
|
||||||
$contact['uid'] = $ok['uid'];
|
$contact['uid'] = $oldContact['uid'];
|
||||||
$contact['owner'] = $ok['owner'];
|
$contact['owner'] = $oldContact['owner'];
|
||||||
$contact['private'] = $ok['private'];
|
$contact['private'] = $oldContact['private'];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$contact['owner'] = $user;
|
$contact['owner'] = $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->http_if_match) $contact['etag'] = self::etag2value($this->http_if_match);
|
if ($this->http_if_match) $contact['etag'] = self::etag2value($this->http_if_match);
|
||||||
|
|
||||||
if (!($save_ok = $this->bo->save($contact)))
|
if (!($save_ok = $this->bo->save($contact)))
|
||||||
@ -309,18 +342,19 @@ class addressbook_groupdav extends groupdav_handler
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($contact['etag']))
|
if (!isset($contact['etag']))
|
||||||
{
|
{
|
||||||
$contact = $this->read($save_ok);
|
$contact = $this->read($save_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
header('ETag: '.$this->get_etag($contact));
|
header('ETag: '.$this->get_etag($contact));
|
||||||
if (is_null($ok))
|
if ($retval !== true)
|
||||||
{
|
{
|
||||||
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
||||||
header($h='Location: '.$path.self::get_path($contact));
|
header($h='Location: '.$this->base_uri.$path.self::get_path($contact));
|
||||||
if ($this->debug) error_log(__METHOD__."($method,,$id) header('$h'): 201 Created");
|
if ($this->debug) error_log(__METHOD__."($method,,$id) header('$h'): $retval");
|
||||||
return '201 Created';
|
return $retval;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -437,16 +437,16 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
function put(&$options,$id,$user=null)
|
function put(&$options,$id,$user=null)
|
||||||
{
|
{
|
||||||
if ($this->debug) error_log(__METHOD__."($id, $user)".print_r($options,true));
|
if ($this->debug) error_log(__METHOD__."($id, $user)".print_r($options,true));
|
||||||
$return_no_access=true; // as handled by importVCal anyway and allows it to set the status for participants
|
|
||||||
$event = $this->_common_get_put_delete('PUT',$options,$id,$return_no_access);
|
|
||||||
|
|
||||||
if (!is_null($event) && !is_array($event))
|
$return_no_access=true; // as handled by importVCal anyway and allows it to set the status for participants
|
||||||
|
$oldEvent = $this->_common_get_put_delete('PUT',$options,$id,$return_no_access);
|
||||||
|
if (!is_null($oldEvent) && !is_array($oldEvent))
|
||||||
{
|
{
|
||||||
if ($this->debug) error_log(__METHOD__.print_r($event,true).function_backtrace());
|
if ($this->debug) error_log(__METHOD__.print_r($oldEvent,true).function_backtrace());
|
||||||
return $event;
|
return $oldEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($event) && !$this->bo->check_perms(EGW_ACL_ADD, 0, $user))
|
if (is_null($oldEvent) && !$this->bo->check_perms(EGW_ACL_ADD, 0, $user))
|
||||||
{
|
{
|
||||||
// we have not permission on this user's calendar
|
// we have not permission on this user's calendar
|
||||||
if ($this->debug) error_log(__METHOD__."(,$user) we have not enough rights on this calendar");
|
if ($this->debug) error_log(__METHOD__."(,$user) we have not enough rights on this calendar");
|
||||||
@ -456,7 +456,46 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
$handler = $this->_get_handler();
|
$handler = $this->_get_handler();
|
||||||
$vCalendar = htmlspecialchars_decode($options['content']);
|
$vCalendar = htmlspecialchars_decode($options['content']);
|
||||||
|
|
||||||
if (!($cal_id = $handler->importVCal($vCalendar, is_numeric($id) ? $id : -1,
|
if (is_array($oldEvent))
|
||||||
|
{
|
||||||
|
$eventId = $oldEvent['id'];
|
||||||
|
if ($return_no_access)
|
||||||
|
{
|
||||||
|
$retval = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// let lightning think the event is added
|
||||||
|
$retval = '201 Created';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new entry?
|
||||||
|
if (($foundEvents = $handler->search($vCalendar)))
|
||||||
|
{
|
||||||
|
if (($eventId = array_shift($foundEvents)) &&
|
||||||
|
(list($eventId) = explode(':', $eventId)) &&
|
||||||
|
($oldEvent = $this->bo->read($eventId)))
|
||||||
|
{
|
||||||
|
$retval = '301 Moved Permanently';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// to be safe
|
||||||
|
$eventId = -1;
|
||||||
|
$retval = '201 Created';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new entry
|
||||||
|
$eventId = -1;
|
||||||
|
$retval = '201 Created';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!($cal_id = $handler->importVCal($vCalendar, $eventId,
|
||||||
self::etag2value($this->http_if_match), false, 0, $this->principalURL, $user)))
|
self::etag2value($this->http_if_match), false, 0, $this->principalURL, $user)))
|
||||||
{
|
{
|
||||||
if ($this->debug) error_log(__METHOD__."(,$id) importVCal($options[content]) returned false");
|
if ($this->debug) error_log(__METHOD__."(,$id) importVCal($options[content]) returned false");
|
||||||
@ -464,12 +503,12 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
header('ETag: '.$this->get_etag($cal_id));
|
header('ETag: '.$this->get_etag($cal_id));
|
||||||
if (is_null($event) || !$return_no_access) // let lightning think the event is added
|
if ($retval !== true)
|
||||||
{
|
{
|
||||||
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
||||||
if ($this->debug) error_log(__METHOD__."(,$id,$user) cal_id=$cal_id, is_null(\$event)=".(int)is_null($event));
|
if ($this->debug) error_log(__METHOD__."(,$id,$user) cal_id=$cal_id: $retval");
|
||||||
header('Location: '.$path.self::get_path($cal_id));
|
header('Location: '.$this->base_uri.$path.self::get_path($cal_id));
|
||||||
return '201 Created';
|
return $retval;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -193,26 +193,61 @@ class infolog_groupdav extends groupdav_handler
|
|||||||
*/
|
*/
|
||||||
function put(&$options,$id,$user=null)
|
function put(&$options,$id,$user=null)
|
||||||
{
|
{
|
||||||
$ok = $this->_common_get_put_delete('PUT',$options,$id);
|
if ($this->debug) error_log(__METHOD__."($id, $user)".print_r($options,true));
|
||||||
if (!is_null($ok) && !is_array($ok))
|
|
||||||
|
$oldTask = $this->_common_get_put_delete('PUT',$options,$id);
|
||||||
|
if (!is_null($oldTask) && !is_array($oldTask))
|
||||||
{
|
{
|
||||||
return $ok;
|
return $oldTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler = $this->_get_handler();
|
$handler = $this->_get_handler();
|
||||||
$vTodo = htmlspecialchars_decode($options['content']);
|
$vTodo = htmlspecialchars_decode($options['content']);
|
||||||
|
|
||||||
if (!($info_id = $handler->importVTODO($vTodo,is_numeric($id) ? $id : -1, false, $user)))
|
if (is_array($oldTask))
|
||||||
|
{
|
||||||
|
$taskId = $oldTask['info_id'];
|
||||||
|
$retval = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new entry?
|
||||||
|
if (($foundTasks = $handler->searchVTODO($vTodo)))
|
||||||
|
{
|
||||||
|
if (($taskId = array_shift($foundTasks)) &&
|
||||||
|
($oldTask = $this->bo->read($taskId)))
|
||||||
|
{
|
||||||
|
$retval = '301 Moved Permanently';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// to be safe
|
||||||
|
$taskId = -1;
|
||||||
|
$retval = '201 Created';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new entry
|
||||||
|
$taskId = -1;
|
||||||
|
$retval = '201 Created';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!($infoId = $handler->importVTODO($vTodo, $taskId, false, $user)))
|
||||||
{
|
{
|
||||||
if ($this->debug) error_log(__METHOD__."(,$id) import_vtodo($options[content]) returned false");
|
if ($this->debug) error_log(__METHOD__."(,$id) import_vtodo($options[content]) returned false");
|
||||||
return '403 Forbidden';
|
return '403 Forbidden';
|
||||||
}
|
}
|
||||||
header('ETag: '.$this->get_etag($info_id));
|
|
||||||
if (is_null($ok) || $id != $info_id)
|
if ($infoId != $taskId) $retval = '201 Created';
|
||||||
|
|
||||||
|
header('ETag: '.$this->get_etag($infoId));
|
||||||
|
if ($retval !== true)
|
||||||
{
|
{
|
||||||
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
||||||
header('Location: '.$path.self::get_path($info_id));
|
header('Location: '.$this->base_uri.$path.self::get_path($infoId));
|
||||||
return '201 Created';
|
return $retval;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ abstract class groupdav_handler
|
|||||||
* @param array &$options
|
* @param array &$options
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @param boolean &$return_no_access=false if set to true on call, instead of '403 Forbidden' the entry is returned and $return_no_access===false
|
* @param boolean &$return_no_access=false if set to true on call, instead of '403 Forbidden' the entry is returned and $return_no_access===false
|
||||||
* @return array/string entry on success, string with http-error-code on failure, null for PUT on an unknown id
|
* @return array|string entry on success, string with http-error-code on failure, null for PUT on an unknown id
|
||||||
*/
|
*/
|
||||||
function _common_get_put_delete($method,&$options,$id,&$return_no_access=false)
|
function _common_get_put_delete($method,&$options,$id,&$return_no_access=false)
|
||||||
{
|
{
|
||||||
@ -463,7 +463,7 @@ class groupdav_propfind_iterator implements Iterator
|
|||||||
*/
|
*/
|
||||||
public function key()
|
public function key()
|
||||||
{
|
{
|
||||||
$current = $this->current();
|
$current = current($this->files);
|
||||||
|
|
||||||
if ($this->debug) error_log(__METHOD__."() returning ".array2string($current['path']));
|
if ($this->debug) error_log(__METHOD__."() returning ".array2string($current['path']));
|
||||||
return $current['path']; // we return path as key
|
return $current['path']; // we return path as key
|
||||||
|
Loading…
Reference in New Issue
Block a user