* InfoLog/CalDAV: allowing clients to specify URL (name-part), as required by CalDAV spec

This commit is contained in:
Ralf Becker
2011-04-11 09:29:39 +00:00
parent 4c24ac26b2
commit fd56c47151
7 changed files with 177 additions and 156 deletions

View File

@ -1,12 +1,12 @@
<?php <?php
/** /**
* InfoLog - Business object * EGroupware - InfoLog - Business object
* *
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @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-10 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2003-11 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$
*/ */
@ -54,7 +54,7 @@ class infolog_bo
* *
* @var array * @var array
*/ */
var $timestamps = array('info_startdate','info_enddate','info_datemodified','info_datecompleted'); var $timestamps = array('info_startdate','info_enddate','info_datemodified','info_datecompleted','info_created');
/** /**
* fields the responsible user can change * fields the responsible user can change
* *
@ -521,7 +521,7 @@ class infolog_bo
/** /**
* Read an infolog entry specified by $info_id * Read an infolog entry specified by $info_id
* *
* @param int|array $info_id integer id or array with key 'info_id' of the entry to read * @param int|array $info_id integer id or array with id's or array with column=>value pairs of the entry to read
* @param boolean $run_link_id2from=true should link_id2from run, default yes, * @param boolean $run_link_id2from=true should link_id2from run, default yes,
* need to be set to false if called from link-title to prevent an infinit recursion * need to be set to false if called from link-title to prevent an infinit recursion
* @param string $date_format='ts' date-formats: 'ts'=timestamp, 'server'=timestamp in server-time, * @param string $date_format='ts' date-formats: 'ts'=timestamp, 'server'=timestamp in server-time,
@ -531,9 +531,17 @@ class infolog_bo
*/ */
function &read($info_id,$run_link_id2from=true,$date_format='ts') function &read($info_id,$run_link_id2from=true,$date_format='ts')
{ {
if (is_array($info_id)) //error_log(__METHOD__.'('.array2string($info_id).', '.array2string($run_link_id2from).", '$date_format') ".function_backtrace());
if (is_scalar($info_id) || isset($info_id[0]))
{ {
$info_id = isset($info_id['info_id']) ? $info_id['info_id'] : $info_id[0]; if (is_scalar($info_id) && !is_numeric($info_id))
{
$info_id = array('info_uid' => $info_id);
}
else
{
$info_id = array('info_id' => $info_id);
}
} }
if (($data = $this->so->read($info_id)) === False) if (($data = $this->so->read($info_id)) === False)
@ -587,11 +595,11 @@ class infolog_bo
{ {
$info_id = (int)(isset($info_id[0]) ? $info_id[0] : (isset($info_id['info_id']) ? $info_id['info_id'] : $info_id['info_id'])); $info_id = (int)(isset($info_id[0]) ? $info_id[0] : (isset($info_id['info_id']) ? $info_id['info_id'] : $info_id['info_id']));
} }
if ($this->so->read($info_id) === False) if (($info = $this->so->read(array('info_id' => $info_id), true, 'server')) === False)
{ {
return False; return False;
} }
if (!$this->check_access($info_id,EGW_ACL_DELETE)) if (!$this->check_access($info,EGW_ACL_DELETE))
{ {
return False; return False;
} }
@ -613,8 +621,6 @@ class infolog_bo
} }
} }
} }
if (!($info = $this->read($info_id, true, 'server'))) return false; // should not happen
$deleted = $info; $deleted = $info;
$deleted['info_status'] = 'deleted'; $deleted['info_status'] = 'deleted';
$deleted['info_datemodified'] = time(); $deleted['info_datemodified'] = time();
@ -834,8 +840,15 @@ class infolog_bo
} }
if ($touch_modified || !$values['info_modifier']) if ($touch_modified || !$values['info_modifier'])
{ {
$values['info_modifier'] = $this->so->user; $values['info_modifier'] = $to_write['info_modifier'] = $this->so->user;
$to_write['info_modifier'] = $this->so->user; }
// set created and creator for new entries
if (!$values['info_id'])
{
$values['info_created'] = $this->user_time_now;
$to_write['info_created'] = $this->now;
$values['info_creator'] = $to_write['info_creator'] = $this->so->user;
} }
//_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');
@ -847,7 +860,7 @@ class infolog_bo
} }
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) if (!isset($values['info_type']) || $status_only || empty($values['caldav_url']))
{ {
$values = $this->read($info_id, true, 'server'); $values = $this->read($info_id, true, 'server');
} }
@ -902,7 +915,7 @@ class infolog_bo
$values = array_merge($values,$missing_fields); $values = array_merge($values,$missing_fields);
} }
// Add keys missing in the $to_write array // Add keys missing in the $to_write array
if ($missing_fields = array_diff_key($values,$to_write)) if (($missing_fields = array_diff_key($values,$to_write)))
{ {
$to_write = array_merge($to_write,$missing_fields); $to_write = array_merge($to_write,$missing_fields);
} }
@ -940,7 +953,7 @@ class infolog_bo
*/ */
function &search(&$query) function &search(&$query)
{ {
//echo "<p>boinfolog::search(".print_r($query,True).")</p>\n"; //error_log(__METHOD__.'('.array2string($query).')');
if (!isset($query['date_format']) || $query['date_format'] != 'server') if (!isset($query['date_format']) || $query['date_format'] != 'server')
{ {
if (isset($query['col_filter'])) if (isset($query['col_filter']))

View File

@ -1,20 +1,20 @@
<?php <?php
/** /**
* eGroupWare: GroupDAV access: infolog handler * EGroupware: GroupDAV access: infolog handler
* *
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @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
* @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-9 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2007-11 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @version $Id$ * @version $Id$
*/ */
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
/** /**
* eGroupWare: GroupDAV access: infolog handler * EGroupware: GroupDAV access: infolog handler
*/ */
class infolog_groupdav extends groupdav_handler class infolog_groupdav extends groupdav_handler
{ {
@ -43,6 +43,14 @@ class infolog_groupdav extends groupdav_handler
'LOCATION' => 'info_location', 'LOCATION' => 'info_location',
'COMPLETED' => 'info_datecompleted', 'COMPLETED' => 'info_datecompleted',
); );
/**
* Are we using info_id, info_uid or caldav_name for the path/url
*
* Get's set in constructor to 'caldav_name' and groupdav_handler::$path_extension = ''!
*/
static $path_attr = 'info_id';
/** /**
* Constructor * Constructor
* *
@ -57,9 +65,14 @@ class infolog_groupdav extends groupdav_handler
$this->bo = new infolog_bo(); $this->bo = new infolog_bo();
$this->vCalendar = new Horde_iCalendar; $this->vCalendar = new Horde_iCalendar;
}
const PATH_ATTRIBUTE = 'info_id'; // since 1.9.002 we allow clients to specify the URL when creating a new event, as specified by CalDAV
if (version_compare($GLOBALS['egw_info']['apps']['calendar']['version'], '1.9.002', '>='))
{
self::$path_attr = 'caldav_name';
groupdav_handler::$path_extension = '';
}
}
/** /**
* Create the path for an event * Create the path for an event
@ -69,16 +82,16 @@ class infolog_groupdav extends groupdav_handler
*/ */
static function get_path($info) static function get_path($info)
{ {
if (is_numeric($info) && self::PATH_ATTRIBUTE == 'info_id') if (is_numeric($info) && self::$path_attr == 'info_id')
{ {
$name = $info; $name = $info;
} }
else else
{ {
if (!is_array($info)) $info = $this->bo->read($info); if (!is_array($info)) $info = $this->bo->read($info);
$name = $info[self::PATH_ATTRIBUTE]; $name = $info[self::$path_attr];
} }
return $name.'.ics'; return $name.groupdav_handler::$path_extension;
} }
/** /**
@ -176,7 +189,7 @@ class infolog_groupdav extends groupdav_handler
if (!$calendar_data) if (!$calendar_data)
{ {
$query['cols'] = array('info_id', 'info_datemodified'); $query['cols'] = array('info_id', 'info_datemodified', 'info_uid', 'caldav_name');
} }
if (is_array($start)) if (is_array($start))
@ -200,10 +213,9 @@ class infolog_groupdav extends groupdav_handler
HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($task)), HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($task)),
HTTP_WebDAV_Server::mkprop('getcontenttype',$this->agent != 'kde' ? HTTP_WebDAV_Server::mkprop('getcontenttype',$this->agent != 'kde' ?
'text/calendar; charset=utf-8; component=VTODO' : 'text/calendar'), // Konqueror (3.5) dont understand it otherwise 'text/calendar; charset=utf-8; component=VTODO' : 'text/calendar'), // Konqueror (3.5) dont understand it otherwise
// getlastmodified and getcontentlength are required by WebDAV and Cadaver eg. reports 404 Not found if not set // getlastmodified and getcontentlength are required by WebDAV and Cadaver eg. reports 404 Not found if not set
HTTP_WebDAV_Server::mkprop('getlastmodified', $task['info_datemodified']), HTTP_WebDAV_Server::mkprop('getlastmodified', $task['info_datemodified']),
HTTP_WebDAV_Server::mkprop('resourcetype',''), // DAVKit requires that attribute! HTTP_WebDAV_Server::mkprop('resourcetype',''), // DAVKit requires that attribute!
HTTP_WebDAV_Server::mkprop('getcontentlength',''),
); );
if ($calendar_data) if ($calendar_data)
{ {
@ -296,14 +308,8 @@ class infolog_groupdav extends groupdav_handler
$ids = array(); $ids = array();
if ($id) if ($id)
{ {
if (is_numeric($id)) $cal_filters[self::$path_attr] = groupdav_handler::$path_extension ?
{ basename($id,groupdav_handler::$path_extension) : $id;
$cal_filters['info_id'] = $id;
}
else
{
$cal_filters['info_uid'] = basename($id,'.ics');
}
} }
else // fetch all given url's else // fetch all given url's
{ {
@ -312,13 +318,13 @@ class infolog_groupdav extends groupdav_handler
if ($option['name'] == 'href') if ($option['name'] == 'href')
{ {
$parts = explode('/',$option['data']); $parts = explode('/',$option['data']);
if (is_numeric($id = basename(array_pop($parts),'.ics'))) $ids[] = $id; if (($id = basename(array_pop($parts))))
{
$cal_filters[self::$path_attr][] = groupdav_handler::$path_extension ?
basename($id,groupdav_handler::$path_extension) : $id;
}
} }
} }
if ($ids)
{
$cal_filters[] = 'info_id IN ('.implode(',',array_map(create_function('$n','return (int)$n;'),$ids)).')';
}
} }
if ($this->debug > 1) error_log(__METHOD__ ."($options[path],...,$id) calendar-multiget: ids=".implode(',',$ids)); if ($this->debug > 1) error_log(__METHOD__ ."($options[path],...,$id) calendar-multiget: ids=".implode(',',$ids));
} }
@ -341,7 +347,7 @@ class infolog_groupdav extends groupdav_handler
return $task; return $task;
} }
$handler = $this->_get_handler(); $handler = $this->_get_handler();
$options['data'] = $handler->exportVTODO($id,'2.0','PUBLISH'); $options['data'] = $handler->exportVTODO($task,'2.0','PUBLISH');
$options['mimetype'] = 'text/calendar; charset=utf-8'; $options['mimetype'] = 'text/calendar; charset=utf-8';
header('Content-Encoding: identity'); header('Content-Encoding: identity');
header('ETag: '.$this->get_etag($task)); header('ETag: '.$this->get_etag($task));
@ -375,29 +381,10 @@ class infolog_groupdav extends groupdav_handler
$taskId = $oldTask['info_id']; $taskId = $oldTask['info_id'];
$retval = true; $retval = true;
} }
else else // new entry
{ {
// new entry? $taskId = 0;
if (($foundTasks = $handler->searchVTODO($vTodo))) $retval = '201 Created';
{
if (($taskId = array_shift($foundTasks)) &&
($oldTask = $this->bo->read($taskId)))
{
$retval = '301 Moved Permanently';
}
else
{
// to be safe
$taskId = 0;
$retval = '201 Created';
}
}
else
{
// new entry
$taskId = 0;
$retval = '201 Created';
}
} }
if ($user) if ($user)
{ {
@ -422,57 +409,26 @@ class infolog_groupdav extends groupdav_handler
// More like the GUI would be to add it for current user and delegate it to $user. // 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))) 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");
return '403 Forbidden'; return '403 Forbidden';
} }
/*
if (strstr($option['path'], '/infolog/') === 0)
{
$task_filter= 'own';
}
else
{
if ($myself)
{
$task_filter = 'open';
}
else
{
$task_filter = 'user' . $user. '-open';
}
}
$query = array(
'order' => 'info_datemodified',
'sort' => 'DESC',
'filter' => $task_filter,
'date_format' => 'server',
'col_filter' => array('info_id' => $infoId),
);
if (!$this->bo->search($query))
{
$retval = '410 Gone';
}
else
*/
if ($infoId != $taskId) if ($infoId != $taskId)
{ {
$retval = '201 Created'; $retval = '201 Created';
} }
header('ETag: '.$this->get_etag($infoId)); header('ETag: '.$this->get_etag($infoId));
if ($retval !== true)
// send GroupDAV Location header only if we dont use caldav_name as path-attribute
if ($retval !== true && self::$path_attr != 'caldav_name')
{ {
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']); $path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
header('Location: '.$this->base_uri.$path.self::get_path($infoId)); header('Location: '.$this->base_uri.$path.self::get_path($infoId));
return $retval;
} }
return true; return $retval;
} }
/** /**
@ -488,31 +444,31 @@ class infolog_groupdav extends groupdav_handler
{ {
return $task; return $task;
} }
return $this->bo->delete($id); return $this->bo->delete($task['info_id']);
} }
/** /**
* Read an entry * Read an entry
* *
* @param string/id $id * @param string|id $id
* @return array/boolean array with entry, false if no read rights, null if $id does not exist * @return array|boolean array with entry, false if no read rights, null if $id does not exist
*/ */
function read($id) function read($id)
{ {
if (is_numeric($id)) return $this->bo->read($id,false,'server'); return $this->bo->read(array(self::$path_attr => $id),false,'server');
return null;
} }
/** /**
* Check if user has the neccessary rights on a task / infolog entry * Check if user has the neccessary rights on a task / infolog entry
* *
* @param int $acl EGW_ACL_READ, EGW_ACL_EDIT or EGW_ACL_DELETE * @param int $acl EGW_ACL_READ, EGW_ACL_EDIT or EGW_ACL_DELETE
* @param array/int $task task-array or id * @param array|int $task task-array or id
* @return boolean null if entry does not exist, false if no access, true if access permitted * @return boolean null if entry does not exist, false if no access, true if access permitted
*/ */
function check_access($acl,$task) function check_access($acl,$task)
{ {
if (is_null($task)) return true; if (is_null($task)) return true;
return $this->bo->check_access($task,$acl); return $this->bo->check_access($task,$acl);
} }
@ -563,8 +519,10 @@ class infolog_groupdav extends groupdav_handler
/** /**
* Get the etag for an infolog entry * Get the etag for an infolog entry
* *
* @param array/int $info array with infolog entry or info_id * etag currently uses the modifcation time (info_modified), 1.9.002 adds etag column, but it's not yet used!
* @return string/boolean string with etag or false *
* @param array|int $info array with infolog entry or info_id
* @return string|boolean string with etag or false
*/ */
function get_etag($info) function get_etag($info)
{ {

View File

@ -1,10 +1,11 @@
<?php <?php
/** /**
* InfoLog - iCalendar Parser * EGroupware - InfoLog - iCalendar Parser
* *
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @author Lars Kneschke <lkneschke@egroupware.org> * @author Lars Kneschke <lkneschke@egroupware.org>
* @author Joerg Lehrke <jlehrke@noc.de> * @author Joerg Lehrke <jlehrke@noc.de>
* @author Ralf Becker <RalfBecker@outdoor-training.de>
* @package infolog * @package infolog
* @subpackage syncml * @subpackage syncml
* @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
@ -15,7 +16,6 @@ require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
/** /**
* InfoLog: Create and parse iCal's * InfoLog: Create and parse iCal's
*
*/ */
class infolog_ical extends infolog_bo class infolog_ical extends infolog_bo
{ {
@ -157,8 +157,8 @@ class infolog_ical extends infolog_bo
$taskData['info_cat'] = $cats[0]; $taskData['info_cat'] = $cats[0];
} }
$taskData = $GLOBALS['egw']->translation->convert($taskData, $taskData = translation::convert($taskData,
$GLOBALS['egw']->translation->charset(), $charset); translation::charset(), $charset);
if ($this->log) if ($this->log)
{ {
@ -320,8 +320,10 @@ class infolog_ical extends infolog_bo
} }
$vevent->setAttribute('DTSTAMP',time()); $vevent->setAttribute('DTSTAMP',time());
$vevent->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$_taskID,'add')); $vevent->setAttribute('CREATED', $taskData['info_created'] ? $taskData['info_created'] :
$vevent->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$_taskID,'modify')); $GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$taskData['info_id'],'add'));
$vevent->setAttribute('LAST-MODIFIED', $taskData['info_datemodified'] ? $taskData['info_datemodified'] :
$GLOBALS['egw']->contenthistory->getTSforAction('infolog_task',$taskData['info_id'],'modify'));
$vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE'); $vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
$vevent->setAttribute('STATUS',$this->status2vtodo($taskData['info_status'])); $vevent->setAttribute('STATUS',$this->status2vtodo($taskData['info_status']));
// we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS // we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
@ -423,12 +425,12 @@ class infolog_ical extends infolog_bo
* @param int $_taskID=-1 info_id, default -1 = new entry * @param int $_taskID=-1 info_id, default -1 = new entry
* @param boolean $merge=false merge data with existing entry * @param boolean $merge=false merge data with existing entry
* @param int $user=null delegate new task to this account_id, default null * @param int $user=null delegate new task to this account_id, default null
* @param string $charset The encoding charset for $text. Defaults to * @param string $charset=null The encoding charset for $text. Defaults to
* utf-8 for new format, iso-8859-1 for old format. * utf-8 for new format, iso-8859-1 for old format.
* * @param string $caldav_name=null CalDAV URL name-part for new entries
* @return int|boolean integer info_id or false on error * @return int|boolean integer info_id or false on error
*/ */
function importVTODO(&$_vcalData, $_taskID=-1, $merge=false, $user=null, $charset=null) function importVTODO(&$_vcalData, $_taskID=-1, $merge=false, $user=null, $charset=null, $caldav_name=null)
{ {
if ($this->tzid) if ($this->tzid)
@ -468,6 +470,10 @@ class infolog_ical extends infolog_bo
array2string($taskData)."\n",3,$this->logfile); array2string($taskData)."\n",3,$this->logfile);
} }
if ($caldav_name)
{
$taskData['caldav_name'] = $caldav_name;
}
return $this->write($taskData, true, true, false); return $this->write($taskData, true, true, false);
} }
@ -701,8 +707,8 @@ class infolog_ical extends infolog_bo
{ {
if(!($note = $this->read($_noteID, true, 'server'))) return false; if(!($note = $this->read($_noteID, true, 'server'))) return false;
$note = $GLOBALS['egw']->translation->convert($note, $note = translation::convert($note,
$GLOBALS['egw']->translation->charset(), $charset); translation::charset(), $charset);
switch ($_type) switch ($_type)
{ {
@ -714,8 +720,8 @@ class infolog_ical extends infolog_bo
if (!empty($note['info_cat'])) if (!empty($note['info_cat']))
{ {
$cats = $this->get_categories(array($note['info_cat'])); $cats = $this->get_categories(array($note['info_cat']));
$note['info_cat'] = $GLOBALS['egw']->translation->convert($cats[0], $note['info_cat'] = translation::convert($cats[0],
$GLOBALS['egw']->translation->charset(), $charset); translation::charset(), $charset);
} }
$vnote = new Horde_iCalendar_vnote(); $vnote = new Horde_iCalendar_vnote();
$vNote->setAttribute('VERSION', '1.1'); $vNote->setAttribute('VERSION', '1.1');
@ -860,7 +866,7 @@ class infolog_ical extends infolog_bo
case 'text/plain': case 'text/plain':
$note = array(); $note = array();
$note['info_type'] = 'note'; $note['info_type'] = 'note';
$txt = $GLOBALS['egw']->translation->convert($_data, $charset); $txt = translation::convert($_data, $charset);
$txt = str_replace("\r\n", "\n", $txt); $txt = str_replace("\r\n", "\n", $txt);
if (preg_match('/([^\n]+)\n\n(.*)/m', $txt, $match)) if (preg_match('/([^\n]+)\n\n(.*)/m', $txt, $match))

View File

@ -1,11 +1,11 @@
<?php <?php
/** /**
* InfoLog - Storage object * EGroupare - InfoLog - Storage object
* *
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package infolog * @package infolog
* @copyright (c) 2003-9 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2003-11 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$
*/ */
@ -111,9 +111,9 @@ class infolog_so
elseif ((int) $info != $this->data['info_id']) // already loaded? elseif ((int) $info != $this->data['info_id']) // already loaded?
{ {
// dont change our own internal data, // dont change our own internal data,
// dont use new as it changes $phpgw->db $backup_data = $this->data;
$private_info = $this;
$info = $private_info->read($info); $info = $private_info->read($info);
$this->data = $backup_data;
} }
else else
{ {
@ -355,11 +355,12 @@ class infolog_so
* *
* some cacheing is done to prevent multiple reads of the same entry * some cacheing is done to prevent multiple reads of the same entry
* *
* @param int|string $info_id id or uid of entry * @param array $where where clause for entry to read
* @return array|boolean the entry as array or False on error (eg. entry not found) * @return array|boolean the entry as array or False on error (eg. entry not found)
*/ */
function read($info_id) // did _not_ ensure ACL function read(array $where) // did _not_ ensure ACL
{ {
//error_log(__METHOD__.'('.array2string($where).')');
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
{ {
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']; $minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
@ -369,18 +370,16 @@ class infolog_so
$minimum_uid_length = 8; $minimum_uid_length = 8;
} }
//echo "<p>read($info_id) ".function_backtrace()."</p>\n"; if (!$where || !($this->data = $this->db->select($this->info_table,'*',$where,__LINE__,__FILE__)->fetch()))
if (!$info_id || !$this->db->select($this->info_table,'*',
$this->db->expression($this->info_table,array('info_id'=>$info_id),' OR ',array('info_uid'=>$info_id)),__LINE__,__FILE__) ||
!(($this->data = $this->db->row(true))))
{ {
$this->init( ); $this->init( );
//error_log(__METHOD__.'('.array2string($where).') returning FALSE');
return False; return False;
} }
if (!$this->data['info_uid'] || strlen($this->data['info_uid']) < $minimum_uid_length) {
// entry without uid --> create one based on our info_id and save it // entry without uid --> create one based on our info_id and save it
if (!$this->data['info_uid'] || strlen($this->data['info_uid']) < $minimum_uid_length)
$this->data['info_uid'] = $GLOBALS['egw']->common->generate_uid('infolog', $info_id); {
$this->data['info_uid'] = common::generate_uid('infolog', $this->data['info_id']);
$this->db->update($this->info_table, $this->db->update($this->info_table,
array('info_uid' => $this->data['info_uid']), array('info_uid' => $this->data['info_uid']),
array('info_id' => $this->data['info_id']), __LINE__,__FILE__); array('info_id' => $this->data['info_id']), __LINE__,__FILE__);
@ -389,11 +388,11 @@ class infolog_so
{ {
$this->data['info_responsible'] = $this->data['info_responsible'] ? explode(',',$this->data['info_responsible']) : array(); $this->data['info_responsible'] = $this->data['info_responsible'] ? explode(',',$this->data['info_responsible']) : array();
} }
$this->db->select($this->extra_table,'info_extra_name,info_extra_value',array('info_id'=>$this->data['info_id']),__LINE__,__FILE__); foreach($this->db->select($this->extra_table,'info_extra_name,info_extra_value',array('info_id'=>$this->data['info_id']),__LINE__,__FILE__) as $row)
while ($this->db->next_record())
{ {
$this->data['#'.$this->db->f(0)] = $this->db->f(1); $this->data['#'.$row['info_extra_name']] = $row['info_extra_value'];
} }
//error_log(__METHOD__.'('.array2string($where).') returning '.array2string($this->data));
return $this->data; return $this->data;
} }
@ -577,15 +576,22 @@ class infolog_so
$this->db->insert($this->info_table,$to_write,false,__LINE__,__FILE__); $this->db->insert($this->info_table,$to_write,false,__LINE__,__FILE__);
$info_id = $this->data['info_id'] = $this->db->get_last_insert_id($this->info_table,'info_id'); $info_id = $this->data['info_id'] = $this->db->get_last_insert_id($this->info_table,'info_id');
} }
if (!$this->data['info_uid'] || strlen($this->data['info_uid']) < $minimum_uid_length) { $update = array();
// entry without uid --> create one based on our info_id and save it // entry without (reasonable) uid --> create one based on our info_id and save it
if (!$this->data['info_uid'] || strlen($this->data['info_uid']) < $minimum_uid_length)
$this->data['info_uid'] = $GLOBALS['egw']->common->generate_uid('infolog', $info_id); {
$this->db->update($this->info_table, $update['info_uid'] = $this->data['info_uid'] = common::generate_uid('infolog', $info_id);
array('info_uid' => $this->data['info_uid']), }
// entry without caldav_name --> generate one based on info_id plus '.ics' extension
if (empty($this->data['caldav_name']))
{
$update['caldav_name'] = $this->data['caldav_name'] = $info_id.'.ics';
}
if ($update)
{
$this->db->update($this->info_table,$update,
array('info_id' => $info_id), __LINE__,__FILE__); array('info_id' => $info_id), __LINE__,__FILE__);
} }
@ -675,7 +681,7 @@ class infolog_so
*/ */
function search(&$query) function search(&$query)
{ {
//echo "<p>soinfolog.search(".print_r($query,True).")</p>\n"; //error_log(__METHOD__.'('.array2string($query).')');
$action2app = array( $action2app = array(
'addr' => 'addressbook', 'addr' => 'addressbook',
'proj' => 'projects', 'proj' => 'projects',
@ -737,7 +743,7 @@ class infolog_so
$filtermethod .= ' AND '.$data; $filtermethod .= ' AND '.$data;
continue; continue;
} }
if (substr($col,0,5) != 'info_' && substr($col,0,1)!='#') $col = 'info_'.$col; if ($col[0] != '#' && substr($col,0,5) != 'info_' && isset($table_def['fd']['info_'.$col])) $col = 'info_'.$col;
if (!empty($data) && preg_match('/^[a-z_0-9]+$/i',$col)) if (!empty($data) && preg_match('/^[a-z_0-9]+$/i',$col))
{ {
switch ($col) switch ($col)

View File

@ -6,13 +6,13 @@
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package infolog * @package infolog
* @subpackage setup * @subpackage setup
* @copyright (c) 2003-10 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2003-11 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$
*/ */
$setup_info['infolog']['name'] = 'infolog'; $setup_info['infolog']['name'] = 'infolog';
$setup_info['infolog']['version'] = '1.9.001'; $setup_info['infolog']['version'] = '1.9.002';
$setup_info['infolog']['app_order'] = 5; $setup_info['infolog']['app_order'] = 5;
$setup_info['infolog']['tables'] = array('egw_infolog','egw_infolog_extra'); $setup_info['infolog']['tables'] = array('egw_infolog','egw_infolog_extra');
$setup_info['infolog']['enable'] = 1; $setup_info['infolog']['enable'] = 1;
@ -36,7 +36,7 @@ $setup_info['infolog']['description'] =
<p>Other documents / files can be linked to InfoLog entries and are store in the VFS <p>Other documents / files can be linked to InfoLog entries and are store in the VFS
(eGroupWare\'s virtual file system).</p>'; (eGroupWare\'s virtual file system).</p>';
$setup_info['infolog']['note'] = $setup_info['infolog']['note'] =
'<p>There is a <b>CSV import filter</b> (in the admin-section) to import existing data. '<p>There is a <b>CSV import</b> (in the admin-section) to import existing data.
It allows to interactivly assign fields, customize the values with regular It allows to interactivly assign fields, customize the values with regular
expressions and direct calls to php-functions (e.g. to link the phone calls expressions and direct calls to php-functions (e.g. to link the phone calls
(again) to the addressbook entrys).</p> (again) to the addressbook entrys).</p>
@ -70,4 +70,3 @@ $setup_info['infolog']['depends'][] = array(
'appname' => 'etemplate', 'appname' => 'etemplate',
'versions' => Array('1.7','1.8','1.9') 'versions' => Array('1.7','1.8','1.9')
); );

View File

@ -1,12 +1,12 @@
<?php <?php
/** /**
* InfoLog - Setup * EGroupware - InfoLog - Setup
* *
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package infolog * @package infolog
* @subpackage setup * @subpackage setup
* @copyright (c) 2003-8 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2003-11 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$
*/ */
@ -43,11 +43,15 @@ $phpgw_baseline = array(
'info_location' => array('type' => 'varchar','precision' => '255'), 'info_location' => array('type' => 'varchar','precision' => '255'),
'info_custom_from' => array('type' => 'int','precision' => '1'), 'info_custom_from' => array('type' => 'int','precision' => '1'),
'info_uid' => array('type' => 'varchar','precision' => '255'), 'info_uid' => array('type' => 'varchar','precision' => '255'),
'info_cc' => array('type' => 'varchar','precision' => '255') 'info_cc' => array('type' => 'varchar','precision' => '255'),
'caldav_name' => array('type' => 'varchar','precision' => '64','comment' => 'name part of CalDAV URL, if specified by client'),
'info_etag' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'etag, not yet used'),
'info_created' => array('type' => 'int','precision' => '8'),
'info_creator' => array('type' => 'int','precision' => '4'),
), ),
'pk' => array('info_id'), 'pk' => array('info_id'),
'fk' => array(), 'fk' => array(),
'ix' => array(array('info_owner','info_responsible','info_status','info_startdate'),array('info_id_parent','info_owner','info_responsible','info_status','info_startdate')), 'ix' => array('caldav_name',array('info_owner','info_responsible','info_status','info_startdate'),array('info_id_parent','info_owner','info_responsible','info_status','info_startdate')),
'uc' => array() 'uc' => array()
), ),
'egw_infolog_extra' => array( 'egw_infolog_extra' => array(

View File

@ -6,7 +6,7 @@
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package infolog * @package infolog
* @subpackage setup * @subpackage setup
* @copyright (c) 2003-10 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2003-11 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$
*/ */
@ -645,3 +645,38 @@ function infolog_upgrade1_8()
return $GLOBALS['setup_info']['infolog']['currentver'] = '1.9.001'; return $GLOBALS['setup_info']['infolog']['currentver'] = '1.9.001';
} }
/**
* Add column to store CalDAV name given by client and etag (not yet used!)
*/
function infolog_upgrade1_9_001()
{
$GLOBALS['egw_setup']->oProc->AddColumn('egw_infolog','caldav_name',array(
'type' => 'varchar',
'precision' => '64',
'comment' => 'name part of CalDAV URL, if specified by client'
));
$GLOBALS['egw_setup']->db->query('UPDATE egw_infolog SET caldav_name='.
$GLOBALS['egw_setup']->db->concat(
$GLOBALS['egw_setup']->db->to_varchar('info_id'),"'.ics'"),__LINE__,__FILE__);
$GLOBALS['egw_setup']->oProc->CreateIndex('egw_infolog','caldav_name');
$GLOBALS['egw_setup']->oProc->AddColumn('egw_infolog','info_etag',array(
'type' => 'int',
'precision' => '4',
'default' => '0',
'comment' => 'etag, not yet used'
));
$GLOBALS['egw_setup']->oProc->AddColumn('egw_infolog','info_created',array(
'type' => 'int',
'precision' => '8',
));
$GLOBALS['egw_setup']->oProc->AddColumn('egw_infolog','info_creator',array(
'type' => 'int',
'precision' => '4',
));
return $GLOBALS['setup_info']['infolog']['currentver'] = '1.9.002';
}