* InfoLog/CalDAV: allow updates with implicite rights of responsible user, InfoLog type is kept on update, deduct not set status of client from completed(-percent)

This commit is contained in:
Ralf Becker 2012-01-26 01:49:56 +00:00
parent c9b0ad39f7
commit d401bcc3ad
3 changed files with 49 additions and 61 deletions

View File

@ -6,7 +6,7 @@
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @author Joerg Lehrke <jlehrke@noc.de> * @author Joerg Lehrke <jlehrke@noc.de>
* @package infolog * @package infolog
* @copyright (c) 2003-11 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2003-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$ * @version $Id$
*/ */
@ -706,16 +706,20 @@ class infolog_bo
{ {
return false; return false;
} }
// we need to get the old values to update the links in customfields and for the tracking
if ($values['info_id'])
{
$old = $this->read($values['info_id'], false, 'server');
}
if (($status_only = $values['info_id'] && !$this->check_access($values['info_id'],EGW_ACL_EDIT))) if (($status_only = $values['info_id'] && !$this->check_access($values['info_id'],EGW_ACL_EDIT)))
{ {
if (!isset($values['info_responsible'])) if (!isset($values['info_responsible']))
{ {
if (!($values_read = $this->read($values['info_id']))) return false; $responsible = $old['info_responsible'];
$responsible =& $values_read['info_responsible'];
} }
else else
{ {
$responsible =& $values['info_responsible']; $responsible = $values['info_responsible'];
} }
if (!($status_only = in_array($this->user, (array)$responsible))) // responsible has implicit right to change status if (!($status_only = in_array($this->user, (array)$responsible))) // responsible has implicit right to change status
{ {
@ -736,14 +740,12 @@ class infolog_bo
$set_completed = !$values['info_datecompleted'] && // set date completed of finished job, only if its not already set $set_completed = !$values['info_datecompleted'] && // set date completed of finished job, only if its not already set
(in_array($values['info_status'],array('done','billed','cancelled')) || (int)$values['info_percent'] == 100); (in_array($values['info_status'],array('done','billed','cancelled')) || (int)$values['info_percent'] == 100);
$backup_values = $values; // to return the full values $values = $old;
$values = array( // only overwrite explicitly allowed fields
'info_id' => $values['info_id'], $values['info_datemodified'] = $values_in['info_datemodified'];
'info_datemodified' => $values['info_datemodified'],
);
foreach ($this->responsible_edit as $name) foreach ($this->responsible_edit as $name)
{ {
if (isset($backup_values[$name])) $values[$name] = $backup_values[$name]; if (isset($values_in[$name])) $values[$name] = $values_in[$name];
} }
if ($set_completed) if ($set_completed)
{ {
@ -848,8 +850,6 @@ class infolog_bo
$values['info_from'] = $this->link_id2from($values); $values['info_from'] = $this->link_id2from($values);
} }
if ($status_only && !$undelete) $values = array_merge($backup_values,$values);
$to_write = $values; $to_write = $values;
if ($user2server) if ($user2server)
{ {
@ -902,11 +902,6 @@ class infolog_bo
//_debug_array($values); //_debug_array($values);
// error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($values)."\n",3,'/tmp/infolog'); // error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($values)."\n",3,'/tmp/infolog');
// we need to get the old values to update the links in customfields and for the tracking
if ($values['info_id'])
{
$old = $this->read($values['info_id'], false, 'server');
}
if (($info_id = $this->so->write($to_write,$check_modified))) if (($info_id = $this->so->write($to_write,$check_modified)))
{ {
if (!isset($values['info_type']) || $status_only || empty($values['caldav_url'])) if (!isset($values['info_type']) || $status_only || empty($values['caldav_url']))

View File

@ -7,7 +7,7 @@
* @package infolog * @package infolog
* @subpackage groupdav * @subpackage groupdav
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright (c) 2007-11 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2007-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @version $Id$ * @version $Id$
*/ */
@ -102,33 +102,32 @@ class infolog_groupdav extends groupdav_handler
*/ */
private function get_infolog_filter($path, $user) private function get_infolog_filter($path, $user)
{ {
if (!($infolog_types = $GLOBALS['egw_info']['user']['preferences']['activesync']['infolog-types'])) if (!($infolog_types = $GLOBALS['egw_info']['user']['preferences']['groupdav']['infolog-types']))
{ {
$infolog_types = 'task'; $infolog_types = 'task';
} }
$myself = ($user == $GLOBALS['egw_info']['user']['account_id']);
if ($path == '/infolog/') if ($path == '/infolog/')
{ {
$task_filter= 'own'; $task_filter= 'own';
} }
else else
{ {
if ($myself) if ($user == $GLOBALS['egw_info']['user']['account_id'])
{ {
$task_filter = 'open'; $task_filter = 'own';
} }
else else
{ {
$task_filter = 'open-user' . $user; $task_filter = 'user' . $user;
} }
} }
return array( $ret = array(
'filter' => $task_filter, 'filter' => $task_filter,
'info_type' => explode(',', $infolog_types), 'info_type' => explode(',', $infolog_types),
); );
error_log(__METHOD__."('$path', $user) returning ".array2string($ret));
return $ret;
} }
/** /**
@ -308,10 +307,11 @@ class infolog_groupdav extends groupdav_handler
} }
} }
// if client set an own filter, reset the open-standard filter // if client set an own filter, reset the open-standard filter
/* not longer necessary, as we use now own and user anyway
if ($cal_filters != $cal_filters_in) if ($cal_filters != $cal_filters_in)
{ {
$cal_filters['filter'] = str_replace(array('open', 'open-user'), array('own', 'user'), $cal_filters['filter']); $cal_filters['filter'] = str_replace(array('open', 'open-user'), array('own', 'user'), $cal_filters['filter']);
} }*/
} }
// multiget or propfind on a given id // multiget or propfind on a given id
//error_log(__FILE__ . __METHOD__ . "multiget of propfind:"); //error_log(__FILE__ . __METHOD__ . "multiget of propfind:");
@ -457,29 +457,6 @@ class infolog_groupdav extends groupdav_handler
$taskId = 0; $taskId = 0;
$retval = '201 Created'; $retval = '201 Created';
} }
if ($user)
{
if (!$prefix) // for everything in /infolog/
{
$user = null; // do NOT set current user (infolog_bo->write() set it for new entries anyway)
}
elseif($oldTask) // existing entries
{
if ($oldTask['info_owner'] != $user)
{
if ($this->debug) error_log(__METHOD__."(,$id,$user,$prefix) changing owner of existing entries is forbidden!");
return '403 Forbidden'; // changing owner of existing entries is generally forbidden
}
$user = null;
}
else // new entries in /$user/infolog
{
// ACL is checked in infolog_bo->write() called by infolog_ical->importVTODO().
// Not sure if it's a good idea to set a different owner, as GUI does NOT allow that,
// thought there's an ACL for it and backend (infolog_bo) checks it.
// More like the GUI would be to add it for current user and delegate it to $user.
}
}
if (!($infoId = $handler->importVTODO($vTodo, $taskId, false, $user, null, $id))) if (!($infoId = $handler->importVTODO($vTodo, $taskId, false, $user, null, $id)))
{ {
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");
@ -544,7 +521,14 @@ class infolog_groupdav extends groupdav_handler
{ {
if (is_null($task)) return true; if (is_null($task)) return true;
return $this->bo->check_access($task,$acl); $access = $this->bo->check_access($task,$acl);
if (!$access && $acl == EGW_ACL_EDIT && $this->bo->is_responsible($task))
{
$access = true; // access limited to $this->bo->responsible_edit fields (handled in infolog_bo::write())
}
if ($this->debug > 1) error_log(__METHOD__."($acl, ".array2string($task).') returning '.array2string($access));
return $access;
} }
/** /**

View File

@ -434,21 +434,22 @@ class infolog_ical extends infolog_bo
// keep the dates // keep the dates
$this->time2time($taskData, $this->tzid, false); $this->time2time($taskData, $this->tzid, false);
// we suppose that a not set status in a vtodo means that the task did not started yet
if (empty($taskData['info_status']))
{
$taskData['info_status'] = 'not-started';
}
if (empty($taskData['info_datecompleted'])) if (empty($taskData['info_datecompleted']))
{ {
$taskData['info_datecompleted'] = 0; $taskData['info_datecompleted'] = 0;
} }
if (!is_null($user)) if (!is_null($user) && $_taskID)
{
if ($this->check_access($taskData, EGW_ACL_ADD))
{ {
$taskData['info_owner'] = $user; $taskData['info_owner'] = $user;
} }
else
{
$taskData['info_responsible'][] = $user;
}
}
if ($this->log) if ($this->log)
{ {
@ -553,12 +554,20 @@ class infolog_ical extends infolog_bo
} }
$taskData = array(); $taskData = array();
$taskData['info_type'] = 'task';
if ($_taskID > 0) if ($_taskID > 0)
{ {
$taskData['info_id'] = $_taskID; $taskData['info_id'] = $_taskID;
} }
// if we have no STATUS, set STATUS by existence of COMPLETED and/or PERCENT-COMPLETED
// iOS reminder app only sets COMPLETED, but never STATUS
if (!($attr = $component->getAttribute('STATUS')) || !is_scalar($attr))
{
$status = ($attr=$component->getAttribute('COMPLETED')) && is_scalar($attr) ? 'COMPLETED' :
(($attr=$component->getAttribute('COMPLETED-PERCENT')) && is_scalar($attr) && $attr > 0 ? 'IN-PROCESS' : 'NEEDS-ACTION');
$component->setAttribute('STATUS', $status);
if ($this->log) error_log(__METHOD__."() setting STATUS='$status' from COMPLETED(-PERCENT)\n",3,$this->logfile);
}
foreach ($component->getAllAttributes() as $attribute) foreach ($component->getAllAttributes() as $attribute)
{ {
//$attribute['value'] = trim($attribute['value']); //$attribute['value'] = trim($attribute['value']);
@ -641,7 +650,7 @@ class infolog_ical extends infolog_bo
case 'STATUS': case 'STATUS':
// check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user) // check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user)
$taskData['info_status'] = $this->vtodo2status($attribute['value'], $taskData['info_status'] = $this->vtodo2status($attribute['value'],
($attr=$component->getAttribute('X-INFOLOG-STATUS')) && is_array($attr) ? $attr['value'] : null); ($attr=$component->getAttribute('X-INFOLOG-STATUS')) && is_scalar($attr) ? $attr : null);
break; break;
case 'SUMMARY': case 'SUMMARY':