From a7b3ed7902ce09fd4c7f284b45fd193fbb6ab0b3 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Tue, 7 Oct 2008 14:01:33 +0000 Subject: [PATCH] moved xmlrpc code to own class boinfolog, to keep the old xmlrpc functions and get a cleaner code for no xmlrpc --- infolog/inc/class.boinfolog.inc.php | 311 +++++++++++++++++++++++++++ infolog/inc/class.infolog_bo.inc.php | 237 +------------------- 2 files changed, 316 insertions(+), 232 deletions(-) create mode 100644 infolog/inc/class.boinfolog.inc.php diff --git a/infolog/inc/class.boinfolog.inc.php b/infolog/inc/class.boinfolog.inc.php new file mode 100644 index 0000000000..79dabd1e36 --- /dev/null +++ b/infolog/inc/class.boinfolog.inc.php @@ -0,0 +1,311 @@ + + * @package infolog + * @copyright (c) 2003-8 by Ralf Becker + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @version $Id$ + */ + +/** + * Class to access AND manipulate InfoLog data via XMLRPC or SOAP + * + * eGW's xmlrpc interface is documented at http://egroupware.org/wiki/xmlrpc + * + * @link http://egroupware.org/wiki/xmlrpc + */ +class boinfolog extends infolog_bo +{ + 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') + ), + ); + + /** + * 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. + * + * @param string $_type='xmlrpc' xmlrpc or soap + * @return array + */ + function list_methods($_type='xmlrpc') + { + 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(xmlrpcInt,xmlrpcInt)), + '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(xmlrpcInt,xmlrpcInt)), + 'docstring' => lang('Delete one record by passing its id.') + ), + 'categories' => array( + 'function' => 'categories', + 'signature' => array(array(xmlrpcBoolean,xmlrpcBoolean)), + '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; + } + } + + /** + * 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 + * @return array/boolean infolog entry, null if not found or false if no permission to read it + */ + function &read($info_id) + { + $data = parent::read($info_id); + + if (is_null($data)) + { + $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']); + } + elseif($data === false) + { + $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']); + } + else + { + $data = $this->data2xmlrpc($data); + } + return $data; + } + + /** + * Delete an infolog entry, evtl. incl. it's children / subs + * + * @param array $data array with keys 'info_id', 'delete_children' and 'new_parent' + * @return boolean True if delete was successful, False otherwise ($info_id does not exist or no rights) + */ + function delete($data) + { + if (is_array($info_id)) + { + $delete_children = $info_id['delete_children']; + $new_parent = $info_id['new_parent']; + $info_id = (int)(isset($info_id[0]) ? $info_id[0] : (isset($info_id['info_id']) ? $info_id['info_id'] : $info_id['info_id'])); + } + $status = parent::delete($info_id,$delete_children,$new_parent); + + if ($status === false) + { + $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']); + } + return $status; + } + + /** + * writes the given $values to InfoLog, a new entry gets created if info_id is not set or 0 + * + * checks and asures ACL + * + * @param array &$values values to write, if contains values for check_defaults and touch_modified, + * they have precedens over the parameters. The + * @param boolean $check_defaults=true check and set certain defaults + * @param boolean $touch_modified=true touch the modification data and sets the modiefier's user-id + * @return int/boolean info_id on a successfull write or false + */ + function write(&$values,$check_defaults=True,$touch_modified=True) + { + //echo "boinfolog::write()values="; _debug_array($values); + // allow to (un)set check_defaults and touch_modified via values, eg. via xmlrpc + foreach(array('check_defaults','touch_modified') as $var) + { + if(isset($values[$var])) + { + $$var = $values[$var]; + unset($values[$var]); + } + } + $values = $this->xmlrpc2data($values); + + $status = parent::write($values,$check_defaults,$touch_modified); + + if ($status == false) + { + $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']); + } + return $info_id; + } + + /** + * searches InfoLog for a certain pattern in $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 (!) + * @return array with id's as key of the matching log-entries + */ + function &search(&$query) + { + //echo "

boinfolog::search(".print_r($query,True).")

\n"; + $ret = parent::search($query); + + if (is_array($ret)) + { + $infos =& $ret; + unset($ret); + $ret = array(); + foreach($infos as $id => $data) + { + $ret[] = $this->data2xmlrpc($data); + } + } + //echo "

boinfolog::search(".print_r($query,True).")=

".print_r($ret,True)."
\n"; + return $ret; + } + + /** + * Convert an InfoLog entry into its xmlrpc representation, eg. convert timestamps to datetime.iso8601 + * + * @param array $data infolog entry + * @param array xmlrpc infolog entry + */ + function data2xmlrpc($data) + { + $data['rights'] = $this->so->grants[$data['info_owner']]; + + // translate timestamps + if($data['info_enddate'] == 0) unset($data['info_enddate']); + foreach($this->timestamps as $name) + { + if (isset($data[$name])) + { + $data[$name] = $GLOBALS['server']->date2iso8601($data[$name]); + } + } + $ret[$id]['info_percent'] = (int)$data['info_percent'].'%'; + + // translate cat_id + if (isset($data['info_cat'])) + { + $data['info_cat'] = $GLOBALS['server']->cats2xmlrpc(array($data['info_cat'])); + } + foreach($data as $name => $val) + { + if (substr($name,0,5) == 'info_') + { + unset($data[$name]); + $data[substr($name,5)] = $val; + } + } + // unsetting everything which could result in an typeless + foreach($data as $key => $value) + { + if (is_null($value) || is_array($value) && !$value) + { + unset($data[$key]); + } + } + return $data; + } + + /** + * Convert an InfoLog xmlrpc representation into the internal one, eg. convert datetime.iso8601 to timestamps + * + * @param array $data infolog entry + * @param array xmlrpc infolog entry + */ + function xmlrpc2data($data) + { + foreach($data as $name => $val) + { + if (substr($name,0,5) != 'info_') + { + unset($data[$name]); + $data['info_'.$name] = $val; + } + } + // translate timestamps + foreach($this->timestamps as $name) + { + if (isset($data[$name])) + { + $data[$name] = $GLOBALS['server']->iso86012date($data[$name],True); + } + } + // translate cat_id + if (isset($data['info_cat'])) + { + $cats = $GLOBALS['server']->xmlrpc2cats($data['info_cat']); + $data['info_cat'] = (int)$cats[0]; + } + return $data; + } + + /** + * return array with all infolog categories (for xmlrpc) + * + * @param boolean $complete true returns array with all data for each cat, else only the title is returned + * @return array with cat_id / title or data pairs (see above) + */ + function categories($complete = False) + { + return $GLOBALS['server']->categories($complete); + } +} diff --git a/infolog/inc/class.infolog_bo.inc.php b/infolog/inc/class.infolog_bo.inc.php index 499a8889fb..bafb2fc34b 100644 --- a/infolog/inc/class.infolog_bo.inc.php +++ b/infolog/inc/class.infolog_bo.inc.php @@ -13,7 +13,7 @@ define('EGW_ACL_UNDELETE',EGW_ACL_CUSTOM_1); // undelete right /** - * This class is the BO-layer of InfoLog, it also handles xmlrpc requests + * This class is the BO-layer of InfoLog */ class infolog_bo { @@ -30,31 +30,6 @@ class infolog_bo var $link_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') - ), - ); - var $xmlrpc = False; // called via xmlrpc - var $tz_offset = 0; /** * offset in secconds between user and server-time, @@ -238,9 +213,6 @@ class infolog_bo $this->grants = $GLOBALS['egw']->acl->get_grants('infolog',$this->group_owners ? $this->group_owners : true); $this->so =& new infolog_so($this->grants); - // are we called via xmlrpc? - $this->xmlrpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method; - if ($info_id) { $this->read( $info_id ); @@ -423,20 +395,12 @@ class infolog_bo if (($data = $this->so->read($info_id)) === False) { - if ($this->xmlrpc) - { - $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']); - } return null; } $info_id = $data['info_id']; // in case the uid was specified if (!$this->check_access($data,EGW_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; } @@ -451,17 +415,13 @@ class infolog_bo { if ($data[$time]) $data[$time] += $this->tz_offset_s; } - if ($this->xmlrpc) - { - $data = $this->data2xmlrpc($data); - } return $data; } /** * Delete an infolog entry, evtl. incl. it's children / subs * - * @param int/array $info_id int id or array with keys 'info_id', 'delete_children' and 'new_parent' setting all 3 params + * @param int/array $info_id int id * @param boolean $delete_children should the children be deleted * @param int/boolean $new_parent parent to use for not deleted children if > 0 * @return boolean True if delete was successful, False otherwise ($info_id does not exist or no rights) @@ -470,24 +430,14 @@ class infolog_bo { if (is_array($info_id)) { - $delete_children = $info_id['delete_children']; - $new_parent = $info_id['new_parent']; $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 ($this->xmlrpc) - { - $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']); - } return False; } if (!$this->check_access($info_id,EGW_ACL_DELETE)) { - if ($this->xmlrpc) - { - $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']); - } return False; } // check if we have children and delete or re-parent them @@ -550,8 +500,7 @@ class infolog_bo * * checks and asures ACL * - * @param array &$values values to write, if contains values for check_defaults and touch_modified, - * they have precedens over the parameters. The + * @param array &$values values to write * @param boolean $check_defaults=true check and set certain defaults * @param boolean $touch_modified=true touch the modification data and sets the modiefier's user-id * @return int/boolean info_id on a successfull write or false @@ -559,15 +508,6 @@ class infolog_bo function write(&$values,$check_defaults=True,$touch_modified=True) { //echo "boinfolog::write()values="; _debug_array($values); - // allow to (un)set check_defaults and touch_modified via values, eg. via xmlrpc - foreach(array('check_defaults','touch_modified') as $var) - { - if(isset($values[$var])) - { - $$var = $values[$var]; - unset($values[$var]); - } - } if ($status_only = $values['info_id'] && !$this->check_access($values['info_id'],EGW_ACL_EDIT)) { if (!isset($values['info_responsible'])) @@ -591,16 +531,8 @@ class infolog_bo if ($values['info_id'] && !$this->check_access($values['info_id'],EGW_ACL_EDIT) && !$status_only || !$values['info_id'] && $values['info_id_parent'] && !$this->check_access($values['info_id_parent'],EGW_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); - } if ($status_only && !$undelete) // make sure only status gets writen { $set_completed = !$values['info_datecompleted'] && // set date completed of finished job, only if its not already set @@ -668,7 +600,8 @@ class infolog_bo // Should only an entry be updated which includes the original modification date? // Used in the web-GUI to check against a modification by an other user while editing the entry. // It's now disabled for xmlrpc, as otherwise the xmlrpc code need to be changed! - $check_modified = $values['info_datemodified'] && !$this->xmlrpc ? $values['info_datemodified']-$this->tz_offset_s : false; + $xmprpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method; + $check_modified = $values['info_datemodified'] && !$xmlrpc ? $values['info_datemodified']-$this->tz_offset_s : false; $values['info_datemodified'] = $this->user_time_now; } if ($touch_modified || !$values['info_modifier']) @@ -773,16 +706,6 @@ class infolog_bo } } } - if ($this->xmlrpc && is_array($ret)) - { - $infos =& $ret; - unset($ret); - $ret = array(); - foreach($infos as $id => $data) - { - $ret[] = $this->data2xmlrpc($data); - } - } //echo "

boinfolog::search(".print_r($query,True).")=

".print_r($ret,True)."
\n"; return $ret; } @@ -1034,156 +957,6 @@ class infolog_bo return $to_include; } - /** - * 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. - * - * @param string $_type='xmlrpc' xmlrpc or soap - * @return array - */ - function list_methods($_type='xmlrpc') - { - 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(xmlrpcInt,xmlrpcInt)), - '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(xmlrpcInt,xmlrpcInt)), - 'docstring' => lang('Delete one record by passing its id.') - ), - 'categories' => array( - 'function' => 'categories', - 'signature' => array(array(xmlrpcBoolean,xmlrpcBoolean)), - '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; - } - } - - /** - * Convert an InfoLog entry into its xmlrpc representation, eg. convert timestamps to datetime.iso8601 - * - * @param array $data infolog entry - * @param array xmlrpc infolog entry - */ - function data2xmlrpc($data) - { - $data['rights'] = $this->so->grants[$data['info_owner']]; - - // translate timestamps - if($data['info_enddate'] == 0) unset($data['info_enddate']); - foreach($this->timestamps as $name) - { - if (isset($data[$name])) - { - $data[$name] = $GLOBALS['server']->date2iso8601($data[$name]); - } - } - $ret[$id]['info_percent'] = (int)$data['info_percent'].'%'; - - // translate cat_id - if (isset($data['info_cat'])) - { - $data['info_cat'] = $GLOBALS['server']->cats2xmlrpc(array($data['info_cat'])); - } - foreach($data as $name => $val) - { - if (substr($name,0,5) == 'info_') - { - unset($data[$name]); - $data[substr($name,5)] = $val; - } - } - // unsetting everything which could result in an typeless - foreach($data as $key => $value) - { - if (is_null($value) || is_array($value) && !$value) - { - unset($data[$key]); - } - } - return $data; - } - - /** - * Convert an InfoLog xmlrpc representation into the internal one, eg. convert datetime.iso8601 to timestamps - * - * @param array $data infolog entry - * @param array xmlrpc infolog entry - */ - function xmlrpc2data($data) - { - foreach($data as $name => $val) - { - if (substr($name,0,5) != 'info_') - { - unset($data[$name]); - $data['info_'.$name] = $val; - } - } - // translate timestamps - foreach($this->timestamps as $name) - { - if (isset($data[$name])) - { - $data[$name] = $GLOBALS['server']->iso86012date($data[$name],True); - } - } - // translate cat_id - if (isset($data['info_cat'])) - { - $cats = $GLOBALS['server']->xmlrpc2cats($data['info_cat']); - $data['info_cat'] = (int)$cats[0]; - } - return $data; - } - - /** - * return array with all infolog categories (for xmlrpc) - * - * @param boolean $complete true returns array with all data for each cat, else only the title is returned - * @return array with cat_id / title or data pairs (see above) - */ - function categories($complete = False) - { - return $this->xmlrpc ? $GLOBALS['server']->categories($complete) : False; - } - /** * Returm InfoLog (custom) status icons for projectmanager *