first version of xmlrpc support for infolog

This commit is contained in:
Ralf Becker 2004-03-10 00:58:18 +00:00
parent 0711abd82b
commit c5dd013f18
3 changed files with 289 additions and 76 deletions

View File

@ -37,6 +37,30 @@
var $valid_pathes = array(); var $valid_pathes = array();
var $send_file_ips = array(); var $send_file_ips = array();
var $xmlrpc_methods = array();
var $soap_functions = array(
'read' => array(
'in' => array('int'),
'out' => array('array')
),
'search' => array(
'in' => array('array'),
'out' => array('array')
),
'write' => array(
'in' => array('array'),
'out' => array()
),
'delete' => array(
'in' => array('int'),
'out' => array()
),
'categories' => array(
'in' => array('bool'),
'out' => array('array')
),
);
function boinfolog( $info_id = 0) function boinfolog( $info_id = 0)
{ {
$this->enums = $this->stock_enums = array( $this->enums = $this->stock_enums = array(
@ -108,6 +132,9 @@
$this->tz_offset = $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']; $this->tz_offset = $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'];
$this->tz_offset_sec = 60*60*$this->tz_offset; $this->tz_offset_sec = 60*60*$this->tz_offset;
// are we called via xmlrpc?
$this->xmlrpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method;
$this->read( $info_id); $this->read( $info_id);
} }
@ -178,7 +205,27 @@
function read($info_id) function read($info_id)
{ {
$err = $this->so->read($info_id) === False; if (is_array($info_id))
{
$info_id = (int)$info_id['info_id'];
}
if ($this->so->read($info_id) === False)
{
if ($this->xmlrpc)
{
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']);
}
return False;
}
if (!$this->check_access($info_id,PHPGW_ACL_READ)) // check behind read, to prevent a double read
{
if ($this->xmlrpc)
{
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
}
return False;
}
$data = &$this->so->data; $data = &$this->so->data;
if ($data['info_subject'] == $this->subject_from_des($data['info_des'])) if ($data['info_subject'] == $this->subject_from_des($data['info_des']))
@ -187,11 +234,30 @@
} }
$this->link_id2from($data); $this->link_id2from($data);
return $err ? False : $data; if ($this->xmlrpc)
{
$data = $this->data2xmlrpc($data);
}
return $data;
} }
function delete($info_id,$delete_children,$new_parent) function delete($info_id,$delete_children=False,$new_parent=False)
{ {
if (is_array($info_id))
{
$delete_children = $info_id['delete_children'];
$new_parent = $info_id['new_parent'];
$info_id = $info_id['info_id'];
}
if (!$this->check_access($info_id,PHPGW_ACL_DELETE))
{
if ($this->xmlrpc)
{
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
}
return False;
}
$this->link->unlink(0,'infolog',$info_id); $this->link->unlink(0,'infolog',$info_id);
$this->so->delete($info_id,$delete_children,$new_parent); $this->so->delete($info_id,$delete_children,$new_parent);
@ -199,7 +265,20 @@
function write($values,$check_defaults=True,$touch_modified=True) function write($values,$check_defaults=True,$touch_modified=True)
{ {
while (list($key,$val) = each($values)) if ($values['info_id'] && !$this->check_access($values['info_id'],PHPGW_ACL_EDIT) ||
!$values['info_id'] && $values['info_id_parent'] && !$this->check_access($values['info_id_parent'],PHPGW_ACL_ADD))
{
if ($this->xmlrpc)
{
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
}
return False;
}
if ($this->xmlrpc)
{
$values = $this->xmlrpc2data($values);
}
foreach($values as $key => $val)
{ {
if ($key[0] != '#' && substr($key,0,5) != 'info_') if ($key[0] != '#' && substr($key,0,5) != 'info_')
{ {
@ -247,9 +326,32 @@
return $this->so->anzSubs( $info_id ); return $this->so->anzSubs( $info_id );
} }
function search($order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,&$start,&$total,$col_filter=False) /*!
@function search
@abstract searches InfoLog for a certain pattern in $query
@syntax search( $query )
@param $query[order] column-name to sort after
@param $query[sort] sort-order DESC or ASC
@param $query[filter] string with combination of acl-, date- and status-filters, eg. 'own-open-today' or ''
@param $query[cat_id] category to use or 0 or unset
@param $query[search] pattern to search, search is done in info_from, info_subject and info_des
@param $query[action] / $query[action_id] if only entries linked to a specified app/entry show be used
@param &$query[start], &$query[total] nextmatch-parameters will be used and set if query returns less entries
@param $query[col_filter] array with column-name - data pairs, data == '' means no filter (!)
@returns array with id's as key of the matching log-entries
*/
function search(&$query)
{ {
return $this->so->search($order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,$start,$total,$col_filter); $ret = $this->so->search($query);
if ($this->xmlrpc && is_array($ret))
{
foreach($ret as $id => $data)
{
$ret[$id] = $this->data2xmlrpc($data);
}
}
//echo "<p>boinfolog::search(".print_r($query,True).")=<pre>".print_r($ret,True)."</pre>\n";
return $ret;
} }
/*! /*!
@ -280,13 +382,19 @@
*/ */
function link_query( $pattern ) function link_query( $pattern )
{ {
$start = $total = 0; $query = array(
$ids = $this->search('','','','',$pattern,'','','',&$start,&$total); 'search' => $pattern,
'start' => 0,
);
$ids = $this->search($query);
$content = array(); $content = array();
while (is_array($ids) && list( $id,$info ) = each( $ids )) if (is_array($ids))
{
foreach($ids as $id => $info )
{ {
$content[$id] = $this->link_title($id); $content[$id] = $this->link_title($id);
} }
}
return $content; return $content;
} }
@ -315,11 +423,15 @@
$GLOBALS['phpgw']->translation->add_app('infolog'); $GLOBALS['phpgw']->translation->add_app('infolog');
$do_events = $args['location'] == 'calendar_include_events'; $do_events = $args['location'] == 'calendar_include_events';
$start = 0;
$to_include = array(); $to_include = array();
$date_wanted = sprintf('%04d/%02d/%02d',$args['year'],$args['month'],$args['day']); $date_wanted = sprintf('%04d/%02d/%02d',$args['year'],$args['month'],$args['day']);
while ($infos = $this->search('info_startdate'.($do_events?'':' DESC'),'', $query = array(
"user$user".($do_events?'date':'opentoday').$date_wanted,'','','','','',$start,$total)) 'order' => 'info_startdate',
'sort' => $do_events ? 'ASC' : 'DESC',
'filter'=> "user$user".($do_events ? 'date' : 'opentoday').$date_wanted,
'start' => 0,
);
while ($infos = $this->search($query))
{ {
foreach($infos as $info) foreach($infos as $info)
{ {
@ -352,7 +464,7 @@
'content' => $content 'content' => $content
); );
} }
if ($total <= ($start+=count($infos))) if ($query['total'] <= ($query['start']+=count($infos)))
{ {
break; // no more availible break; // no more availible
} }
@ -360,4 +472,106 @@
//echo "boinfolog::cal_to_include("; print_r($args); echo ")<pre>"; print_r($to_include); echo "</pre>\n"; //echo "boinfolog::cal_to_include("; print_r($args); echo ")<pre>"; print_r($to_include); echo "</pre>\n";
return $to_include; return $to_include;
} }
function list_methods($_type='xmlrpc')
{
/*
** This handles introspection or discovery by the logged in client,
** in which case the input might be an array. The server always calls
** this function to fill the server dispatch map using a string.
*/
if (is_array($_type))
{
$_type = $_type['type'] ? $_type['type'] : $_type[0];
}
switch($_type)
{
case 'xmlrpc':
$xml_functions = array(
'read' => array(
'function' => 'read',
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
'docstring' => lang('Read one record by passing its id.')
),
'search' => array(
'function' => 'search',
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
'docstring' => lang('Returns a list / search for records.')
),
'write' => array(
'function' => 'write',
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
'docstring' => lang('Write (add or update) a record by passing its fields.')
),
'delete' => array(
'function' => 'delete',
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
'docstring' => lang('Delete one record by passing its id.')
),
'categories' => array(
'function' => 'categories',
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
'docstring' => lang('List all categories.')
),
'list_methods' => array(
'function' => 'list_methods',
'signature' => array(array(xmlrpcStruct,xmlrpcString)),
'docstring' => lang('Read this list of methods.')
)
);
return $xml_functions;
break;
case 'soap':
return $this->soap_functions;
break;
default:
return array();
break;
}
}
function data2xmlrpc($data)
{
// translate timestamps
foreach(array('info_startdate','info_enddate','info_datemodified') as $name)
{
if (isset($data[$name]))
{
$data[$name] = $GLOBALS['server']->date2iso8601($data[$name]);
}
}
// translate cat_id
if (isset($data['cat_id']))
{
$data['cat_id'] = $GLOBALS['server']->cats2xmlrpc(array($data['cat_id']));
}
return $data;
}
function xmlrpc2data($data)
{
// translate timestamps
foreach(array('info_startdate','info_enddate','info_datemodified') as $name)
{
if (isset($data[$name]))
{
$data[$name] = $GLOBALS['server']->iso86012date($data[$name],True);
}
}
// translate cat_id
if (isset($data['cat_id']))
{
$cats = $GLOBALS['server']->xmlrpc2cats($data['cat_id']);
$data['cat_id'] = (int)$cats[0];
}
return $data;
}
// return array with all infolog categories (for xmlrpc)
function categories($complete = False)
{
return $GLOBALS['server']->categories($complete);
}
} }

View File

@ -18,7 +18,7 @@
@abstract storage object / db-layer for InfoLog @abstract storage object / db-layer for InfoLog
@author Ralf Becker @author Ralf Becker
@copyright GPL - GNU General Public License @copyright GPL - GNU General Public License
@note all values passed to this class are run either through intval or addslashes to prevent query-inserting @note all values passed to this class are run either through intval or addslashes to prevent query-insertion
and for pgSql 7.3 compatibility and for pgSql 7.3 compatibility
*/ */
class soinfolog // DB-Layer class soinfolog // DB-Layer
@ -104,7 +104,7 @@
} }
if (is_array($this->grants)) if (is_array($this->grants))
{ {
while (list($user,$grant) = each($this->grants)) foreach($this->grants as $user => $grant)
{ {
// echo "<p>grants: user=$user, grant=$grant</p>"; // echo "<p>grants: user=$user, grant=$grant</p>";
if ($grant & (PHPGW_ACL_READ|PHPGW_ACL_EDIT)) if ($grant & (PHPGW_ACL_READ|PHPGW_ACL_EDIT))
@ -180,7 +180,8 @@
@syntax dateFilter($filter = '') @syntax dateFilter($filter = '')
@param $filter upcoming = startdate is in the future<br> @param $filter upcoming = startdate is in the future<br>
today startdate < tomorrow<br> today startdate < tomorrow<br>
overdue enddate < tomorrow overdue enddate < tomorrow<br>
limitYYYY/MM/DD not older or open
@returns the necesary sql @returns the necesary sql
*/ */
function dateFilter($filter = '') function dateFilter($filter = '')
@ -212,6 +213,8 @@
return ''; return '';
} }
return " AND ($today <= info_startdate AND info_startdate < $tomorrow)"; return " AND ($today <= info_startdate AND info_startdate < $tomorrow)";
case 'limit':
return " AND (info_modified >= '$today' OR NOT (info_status IN ('done','billed')))";
} }
return ''; return '';
} }
@ -454,53 +457,51 @@
/*! /*!
@function search @function search
@abstract searches InfoLog for a certain pattern in $query @abstract searches InfoLog for a certain pattern in $query
@syntax search( $order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,&$start,&$total ) @syntax search( $query )
@param $order comma-separated list of columns to order the result (no 'ORDER BY'), eg. 'info_subject DESC' @param $query[order] column-name to sort after
@param $sort comma-separated list of columns to to sort by (incl. 'SORT BY') or '' @param $query[sort] sort-order DESC or ASC
@param $filter string with combination of acl-, date- and status-filters, eg. 'own-open-today' or '' @param $query[filter] string with combination of acl-, date- and status-filters, eg. 'own-open-today' or ''
@param $cat_id category to use or 0 @param $query[cat_id] category to use or 0 or unset
@param $query pattern to search, search is done in info_from, info_subject and info_des @param $query[search] pattern to search, search is done in info_from, info_subject and info_des
@param $action / $action_id if only entries linked to a specified app/entry show be used @param $query[action] / $query[action_id] if only entries linked to a specified app/entry show be used
@param &$start, &$total nextmatch-parameters will be used and set if query returns less entries @param &$query[start], &$query[total] nextmatch-parameters will be used and set if query returns less entries
@param $col_filter array with column-name - data pairs, data == '' means no filter (!) @param $query[col_filter] array with column-name - data pairs, data == '' means no filter (!)
@returns array with id's as key of the matching log-entries @returns array with id's as key of the matching log-entries
*/ */
function search($order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,&$start,&$total,$col_filter=False) function search(&$query)
{ {
//echo "<p>soinfolog.search(order='$order',,filter='$filter',,query='$query',action='$action/$action_id')</p>\n"; //echo "<p>soinfolog.search(".print_r($query,True).")</p>\n";
$action2app = array( $action2app = array(
'addr' => 'addressbook', 'addr' => 'addressbook',
'proj' => 'projects', 'proj' => 'projects',
'event' => 'calendar' 'event' => 'calendar'
); );
if (isset($action2app[$action])) $action = isset($action2app[$query['action']]) ? $action2app[$query['action']] : $query['action'];
{
$action = $action2app[$action];
}
if ($action != '') if ($action != '')
{ {
$links = $this->links->get_links($action=='sp'?'infolog':$action,$action_id,'infolog'); $links = $this->links->get_links($action=='sp'?'infolog':$action,$query['action_id'],'infolog');
if (count($links)) if (count($links))
{ {
$link_extra = ($action == 'sp' ? 'OR' : 'AND').' phpgw_infolog.info_id IN ('.implode(',',$links).')'; $link_extra = ($action == 'sp' ? 'OR' : 'AND').' phpgw_infolog.info_id IN ('.implode(',',$links).')';
} }
} }
if ($order) if ($query['order'])
{ {
$ordermethod = 'ORDER BY ' . $this->db->db_addslashes($order) . ' ' . $this->db->db_addslashes($sort); $ordermethod = 'ORDER BY ' . $this->db->db_addslashes($query['order']) . ' ' . $this->db->db_addslashes($query['sort']);
} }
else else
{ {
$ordermethod = 'ORDER BY info_datemodified DESC'; // newest first $ordermethod = 'ORDER BY info_datemodified DESC'; // newest first
} }
$filtermethod = $this->aclFilter($filter); $filtermethod = $this->aclFilter($query['filter']);
$filtermethod .= $this->statusFilter($filter); $filtermethod .= $this->statusFilter($query['filter']);
$filtermethod .= $this->dateFilter($filter); $filtermethod .= $this->dateFilter($query['filter']);
if (is_array($col_filter)) if (is_array($query['col_filter']))
{ {
foreach($col_filter as $col => $data) foreach($query['col_filter'] as $col => $data)
{ {
$data = $this->db->db_addslashes($data); $data = $this->db->db_addslashes($data);
if (!empty($data)) if (!empty($data))
@ -511,19 +512,19 @@
} }
//echo "<p>filtermethod='$filtermethod'</p>"; //echo "<p>filtermethod='$filtermethod'</p>";
if (intval($cat_id)) if (intval($query['cat_id']))
{ {
$filtermethod .= ' AND info_cat='.intval($cat_id).' '; $filtermethod .= ' AND info_cat='.intval($query['cat_id']).' ';
} }
$join = ''; $join = '';
if ($query) // we search in _from, _subject, _des and _extra_value for $query if ($query['search']) // we search in _from, _subject, _des and _extra_value for $query
{ {
$query = $this->db->db_addslashes($query); $query['search'] = $this->db->db_addslashes($query['query']);
$sql_query = "AND (info_from like '%$query%' OR info_subject ". $sql_query = "AND (info_from like '%$query%' OR info_subject ".
"LIKE '%$query%' OR info_des LIKE '%$query%' OR info_extra_value LIKE '%$query%') "; "LIKE '%$query%' OR info_des LIKE '%$query%' OR info_extra_value LIKE '%$query%') ";
$join = 'LEFT JOIN phpgw_infolog_extra ON phpgw_infolog.info_id=phpgw_infolog_extra.info_id'; $join = 'LEFT JOIN phpgw_infolog_extra ON phpgw_infolog.info_id=phpgw_infolog_extra.info_id';
} }
$pid = 'AND info_id_parent='.($action == 'sp' ? $action_id : 0); $pid = 'AND info_id_parent='.($action == 'sp' ? $query['action_id'] : 0);
if (!$GLOBALS['phpgw_info']['user']['preferences']['infolog']['listNoSubs'] && if (!$GLOBALS['phpgw_info']['user']['preferences']['infolog']['listNoSubs'] &&
$action != 'sp') $action != 'sp')
@ -533,15 +534,15 @@
$ids = array( ); $ids = array( );
if ($action == '' || $action == 'sp' || count($links)) if ($action == '' || $action == 'sp' || count($links))
{ {
$query = "FROM phpgw_infolog $join WHERE ($filtermethod $pid $sql_query) $link_extra"; $sql_query = "FROM phpgw_infolog $join WHERE ($filtermethod $pid $sql_query) $link_extra";
$this->db->query($sql='SELECT DISTINCT phpgw_infolog.info_id '.$query,__LINE__,__FILE__); $this->db->query($sql='SELECT DISTINCT phpgw_infolog.info_id '.$sql_query,__LINE__,__FILE__);
$total = $this->db->num_rows(); $query['total'] = $this->db->num_rows();
if (!$start || $start > $total) if (!$query['start'] || $query['start'] > $query['total'])
{ {
$start = 0; $query['start'] = 0;
} }
$this->db->limit_query($sql="SELECT DISTINCT phpgw_infolog.* $query $ordermethod",$start,__LINE__,__FILE__); $this->db->limit_query($sql="SELECT DISTINCT phpgw_infolog.* $sql_query $ordermethod",$query['start'],__LINE__,__FILE__);
//echo "<p>sql='$sql'</p>\n"; //echo "<p>sql='$sql'</p>\n";
while ($this->db->next_record()) while ($this->db->next_record())
{ {
@ -551,7 +552,7 @@
} }
else else
{ {
$start = $total = 0; $query['start'] = $query['total'] = 0;
} }
return $ids; return $ids;
} }

View File

@ -159,24 +159,23 @@
//echo "<p>uiinfolog.get_rows(start=$query[start],search='$query[search]',filter='$query[filter]',cat_id=$query[cat_id],action='$query[action]/$query[action_id]',col_filter=".print_r($query['col_filter'],True).")</p>\n"; //echo "<p>uiinfolog.get_rows(start=$query[start],search='$query[search]',filter='$query[filter]',cat_id=$query[cat_id],action='$query[action]/$query[action_id]',col_filter=".print_r($query['col_filter'],True).")</p>\n";
$this->save_sessiondata($query); $this->save_sessiondata($query);
$ids = $this->bo->search($query['order'],$query['sort'],$query['filter'],$query['cat_id'], $ids = $this->bo->search($query);
$query['search'],$query['action'],$query['action_id'],$query['ordermethod'],
$query['start'],$total,$query['col_filter']);
if (!is_array($ids)) if (!is_array($ids))
{ {
$ids = array( ); $ids = array( );
} }
$rows = array( $total ); $rows = array( $query['total'] );
$readonlys = array(); $readonlys = array();
foreach($ids as $id => $info) foreach($ids as $id => $info)
{ {
$rows[] = $this->get_info($info,$readonlys,$query['action'],$query['action_id']); $rows[] = $this->get_info($info,$readonlys,$query['action'],$query['action_id']);
} }
//echo "<p>readonlys = "; _debug_array($readonlys); //echo "<p>readonlys = "; _debug_array($readonlys);
//echo "rows=<pre>".print_r($rows,True)."</pre>\n";
reset($rows); reset($rows);
return $total; return $query['total'];
} }
function index($values = 0,$action='',$action_id='',$referer=0,$extra_app_header=False,$return_html=False) function index($values = 0,$action='',$action_id='',$referer=0,$extra_app_header=False,$return_html=False)
@ -253,7 +252,7 @@
$action_id = 0; $action_id = 0;
break; break;
} }
$values['main'][1] = $this->get_info($action_id,&$readonlys['main']); $values['main'][1] = $this->get_info($action_id,$readonlys['main']);
break; break;
} }
$readonlys['cancel'] = $action != 'sp'; $readonlys['cancel'] = $action != 'sp';
@ -298,7 +297,7 @@
return $referer ? $this->tmpl->location($referer) : $this->index(); return $referer ? $this->tmpl->location($referer) : $this->index();
} }
$readonlys = $values = array(); $readonlys = $values = array();
$values['main'][1] = $this->get_info($info_id,&$readonlys['main']); $values['main'][1] = $this->get_info($info_id,$readonlys['main']);
$this->tmpl->read('infolog.delete'); $this->tmpl->read('infolog.delete');
@ -659,8 +658,7 @@
$extra = $this->messages + $this->filters; $extra = $this->messages + $this->filters;
$enums = $this->bo->enums + $this->bo->status; $enums = $this->bo->enums + $this->bo->status;
unset($enums['defaults']); unset($enums['defaults']);
reset($enums); foreach($enums as $key => $msg_arr)
while (list($key,$msg_arr) = each($enums))
{ {
$extra += $msg_arr; $extra += $msg_arr;
} }