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 $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)
{
$this->enums = $this->stock_enums = array(
@ -108,6 +132,9 @@
$this->tz_offset = $GLOBALS['phpgw_info']['user']['preferences']['common']['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);
}
@ -178,7 +205,27 @@
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;
if ($data['info_subject'] == $this->subject_from_des($data['info_des']))
@ -187,11 +234,30 @@
}
$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->so->delete($info_id,$delete_children,$new_parent);
@ -199,7 +265,20 @@
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_')
{
@ -247,9 +326,32 @@
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,12 +382,18 @@
*/
function link_query( $pattern )
{
$start = $total = 0;
$ids = $this->search('','','','',$pattern,'','','',&$start,&$total);
$query = array(
'search' => $pattern,
'start' => 0,
);
$ids = $this->search($query);
$content = array();
while (is_array($ids) && list( $id,$info ) = each( $ids ))
if (is_array($ids))
{
$content[$id] = $this->link_title($id);
foreach($ids as $id => $info )
{
$content[$id] = $this->link_title($id);
}
}
return $content;
}
@ -315,11 +423,15 @@
$GLOBALS['phpgw']->translation->add_app('infolog');
$do_events = $args['location'] == 'calendar_include_events';
$start = 0;
$to_include = array();
$date_wanted = sprintf('%04d/%02d/%02d',$args['year'],$args['month'],$args['day']);
while ($infos = $this->search('info_startdate'.($do_events?'':' DESC'),'',
"user$user".($do_events?'date':'opentoday').$date_wanted,'','','','','',$start,$total))
$query = array(
'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)
{
@ -352,7 +464,7 @@
'content' => $content
);
}
if ($total <= ($start+=count($infos)))
if ($query['total'] <= ($query['start']+=count($infos)))
{
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";
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
@author Ralf Becker
@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
*/
class soinfolog // DB-Layer
@ -72,17 +72,17 @@
}
$owner = $info['info_owner'];
$access_ok = $owner == $this->user || // user has all rights
// ACL only on public entrys || $owner granted _PRIVATE
(!!($this->grants[$owner] & $required_rights) ||
// implicite read-rights for responsible user !!!
$info['info_responsible'] == $this->user && $required_rights == PHPGW_ACL_READ) &&
($info['info_access'] == 'public' ||
!!($this->grants[$owner] & PHPGW_ACL_PRIVATE));
$access_ok = $owner == $this->user || // user has all rights
// ACL only on public entrys || $owner granted _PRIVATE
(!!($this->grants[$owner] & $required_rights) ||
// implicite read-rights for responsible user !!!
$info['info_responsible'] == $this->user && $required_rights == PHPGW_ACL_READ) &&
($info['info_access'] == 'public' ||
!!($this->grants[$owner] & PHPGW_ACL_PRIVATE));
// echo "check_access(info_id=$info_id (owner=$owner, user=$user),required_rights=$required_rights): access".($access_ok?"Ok":"Denied");
return $access_ok;
return $access_ok;
}
/*!
@ -104,7 +104,7 @@
}
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>";
if ($grant & (PHPGW_ACL_READ|PHPGW_ACL_EDIT))
@ -180,7 +180,8 @@
@syntax dateFilter($filter = '')
@param $filter upcoming = startdate is in the future<br>
today startdate < tomorrow<br>
overdue enddate < tomorrow
overdue enddate < tomorrow<br>
limitYYYY/MM/DD not older or open
@returns the necesary sql
*/
function dateFilter($filter = '')
@ -212,6 +213,8 @@
return '';
}
return " AND ($today <= info_startdate AND info_startdate < $tomorrow)";
case 'limit':
return " AND (info_modified >= '$today' OR NOT (info_status IN ('done','billed')))";
}
return '';
}
@ -223,12 +226,12 @@
*/
function init()
{
$this->data = array(
$this->data = array(
'info_owner' => $this->user,
'info_pri' => 'normal'
'info_pri' => 'normal'
);
}
}
/*!
@function db2data
@abstract copy data after a query into $data
@ -454,53 +457,51 @@
/*!
@function search
@abstract searches InfoLog for a certain pattern in $query
@syntax search( $order,$sort,$filter,$cat_id,$query,$action,$action_id,$ordermethod,&$start,&$total )
@param $order comma-separated list of columns to order the result (no 'ORDER BY'), eg. 'info_subject DESC'
@param $sort comma-separated list of columns to to sort by (incl. 'SORT BY') or ''
@param $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 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 &$start, &$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 (!)
@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($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(
'addr' => 'addressbook',
'proj' => 'projects',
'event' => 'calendar'
);
if (isset($action2app[$action]))
{
$action = $action2app[$action];
}
$action = isset($action2app[$query['action']]) ? $action2app[$query['action']] : $query['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))
{
$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
{
$ordermethod = 'ORDER BY info_datemodified DESC'; // newest first
}
$filtermethod = $this->aclFilter($filter);
$filtermethod .= $this->statusFilter($filter);
$filtermethod .= $this->dateFilter($filter);
$filtermethod = $this->aclFilter($query['filter']);
$filtermethod .= $this->statusFilter($query['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);
if (!empty($data))
@ -511,19 +512,19 @@
}
//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 = '';
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 ".
"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';
}
$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'] &&
$action != 'sp')
@ -533,15 +534,15 @@
$ids = array( );
if ($action == '' || $action == 'sp' || count($links))
{
$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__);
$total = $this->db->num_rows();
$sql_query = "FROM phpgw_infolog $join WHERE ($filtermethod $pid $sql_query) $link_extra";
$this->db->query($sql='SELECT DISTINCT phpgw_infolog.info_id '.$sql_query,__LINE__,__FILE__);
$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";
while ($this->db->next_record())
{
@ -551,7 +552,7 @@
}
else
{
$start = $total = 0;
$query['start'] = $query['total'] = 0;
}
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";
$this->save_sessiondata($query);
$ids = $this->bo->search($query['order'],$query['sort'],$query['filter'],$query['cat_id'],
$query['search'],$query['action'],$query['action_id'],$query['ordermethod'],
$query['start'],$total,$query['col_filter']);
$ids = $this->bo->search($query);
if (!is_array($ids))
{
$ids = array( );
}
$rows = array( $total );
$rows = array( $query['total'] );
$readonlys = array();
foreach($ids as $id => $info)
{
$rows[] = $this->get_info($info,$readonlys,$query['action'],$query['action_id']);
}
//echo "<p>readonlys = "; _debug_array($readonlys);
//echo "rows=<pre>".print_r($rows,True)."</pre>\n";
reset($rows);
return $total;
return $query['total'];
}
function index($values = 0,$action='',$action_id='',$referer=0,$extra_app_header=False,$return_html=False)
@ -253,7 +252,7 @@
$action_id = 0;
break;
}
$values['main'][1] = $this->get_info($action_id,&$readonlys['main']);
$values['main'][1] = $this->get_info($action_id,$readonlys['main']);
break;
}
$readonlys['cancel'] = $action != 'sp';
@ -298,7 +297,7 @@
return $referer ? $this->tmpl->location($referer) : $this->index();
}
$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');
@ -659,8 +658,7 @@
$extra = $this->messages + $this->filters;
$enums = $this->bo->enums + $this->bo->status;
unset($enums['defaults']);
reset($enums);
while (list($key,$msg_arr) = each($enums))
foreach($enums as $key => $msg_arr)
{
$extra += $msg_arr;
}