mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-07 16:44:20 +01:00
remove addressbook, calendar and infolog classes for xmlrpc, as we droped xmlrpc support
This commit is contained in:
parent
d3e9f43b94
commit
ad57c7ee86
@ -1,481 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Addressbook - xmlrpc access
|
||||
*
|
||||
* The original addressbook xmlrpc interface was written by Joseph Engo <jengo@phpgroupware.org>
|
||||
* and Miles Lott <milos@groupwhere.org>
|
||||
*
|
||||
* Please note: dont use addressbook_... naming convention, as it would break the existing xmlrpc clients
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @package addressbook
|
||||
* @copyright (c) 2007/8 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to access AND manipulate addressbook data via XMLRPC or SOAP
|
||||
*
|
||||
* eGW's xmlrpc interface is documented at http://egroupware.org/wiki/xmlrpc
|
||||
*
|
||||
* @link http://egroupware.org/wiki/xmlrpc
|
||||
*/
|
||||
class boaddressbook
|
||||
{
|
||||
/**
|
||||
* Instance of the contacts class
|
||||
*
|
||||
* @var contacts
|
||||
*/
|
||||
var $contacts;
|
||||
|
||||
/**
|
||||
* Field-mapping for certain user-agents
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $mapping=array();
|
||||
|
||||
/**
|
||||
* User agent: 'KDE-AddressBook', 'eGWOSync', ...
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $user_agent;
|
||||
|
||||
/**
|
||||
* Contstructor
|
||||
*
|
||||
* @return boaddressbook
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->contacts = $GLOBALS['egw']->contacts;
|
||||
|
||||
// are we called via xmlrpc?
|
||||
if (!is_object($GLOBALS['server']) || !$GLOBALS['server']->last_method)
|
||||
{
|
||||
die('not called via xmlrpc');
|
||||
}
|
||||
$this->set_mapping_for_user_agent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param string/array $_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':
|
||||
return array(
|
||||
'read' => array(
|
||||
'function' => 'read',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Read a single entry by passing the id and fieldlist.')
|
||||
),
|
||||
'save' => array(
|
||||
'function' => 'save',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Write (update or add) a single entry by passing the fields.')
|
||||
),
|
||||
'write' => array( // old 1.2 name
|
||||
'function' => 'save',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Write (update or add) a single entry by passing the fields.')
|
||||
),
|
||||
'delete' => array(
|
||||
'function' => 'delete',
|
||||
'signature' => array(array(xmlrpcString,xmlrpcString)),
|
||||
'docstring' => lang('Delete a single entry by passing the id.')
|
||||
),
|
||||
'search' => array(
|
||||
'function' => 'search',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => lang('Read a list / search for entries.')
|
||||
),
|
||||
'categories' => array(
|
||||
'function' => 'categories',
|
||||
'signature' => array(array(xmlrpcBoolean,xmlrpcBoolean)),
|
||||
'docstring' => lang('List all categories')
|
||||
),
|
||||
'customfields' => array(
|
||||
'function' => 'customfields',
|
||||
'signature' => array(array(xmlrpcArray,xmlrpcArray)),
|
||||
'docstring' => lang('List all customfields')
|
||||
),
|
||||
'list_methods' => array(
|
||||
'function' => 'list_methods',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcString)),
|
||||
'docstring' => lang('Read this list of methods.')
|
||||
)
|
||||
);
|
||||
|
||||
case 'soap':
|
||||
return array(
|
||||
'read' => array(
|
||||
'in' => array('int','struct'),
|
||||
'out' => array('array')
|
||||
),
|
||||
'write' => array(
|
||||
'in' => array('int','struct'),
|
||||
'out' => array()
|
||||
),
|
||||
'categories' => array(
|
||||
'in' => array('bool'),
|
||||
'out' => array('struct')
|
||||
),
|
||||
'customfields' => array(
|
||||
'in' => array('array'),
|
||||
'out'=> array('struct')
|
||||
)
|
||||
);
|
||||
|
||||
default:
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field-mapping for user agents expecting old / other field-names
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function set_mapping_for_user_agent()
|
||||
{
|
||||
//error_log("set_mapping_for_user_agent(): HTTP_USER_AGENT='$_SERVER[HTTP_USER_AGENT]'");
|
||||
switch($this->user_agent = $_SERVER['HTTP_USER_AGENT'])
|
||||
{
|
||||
case 'KDE-AddressBook':
|
||||
$this->mapping = array(
|
||||
'n_fn' => 'fn',
|
||||
'modified' => 'last_mod',
|
||||
'tel_other' => 'ophone',
|
||||
'adr_one_street2' => 'address2',
|
||||
'adr_two_street2' => 'address3',
|
||||
'freebusy_uri' => 'freebusy_url',
|
||||
'grants[owner]' => 'rights',
|
||||
'jpegphoto' => false, // gives errors in KAddressbook, maybe the encoding is wrong
|
||||
'photo' => false, // is uncomplete anyway
|
||||
'private' => 'access', // special handling necessary
|
||||
'adr_one_type' => "'Work'", // defines how KAddresbook labels the address
|
||||
'adr_two_type' => "'Home'",
|
||||
);
|
||||
break;
|
||||
|
||||
case 'eGWOSync': // no idea what is necessary
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* translate array of internal datas to xmlrpc, eg. format bday as iso8601
|
||||
*
|
||||
* @internal
|
||||
* @param array $datas array of contact arrays
|
||||
* @param boolean $read_customfields=false should the customfields be read, default no (contacts::read() does it already)
|
||||
* @return array
|
||||
*/
|
||||
function data2xmlrpc($datas,$read_customfields=false)
|
||||
{
|
||||
if(is_array($datas))
|
||||
{
|
||||
if ($read_customfields)
|
||||
{
|
||||
$ids = array();
|
||||
foreach($datas as $data)
|
||||
{
|
||||
$ids[] = $data['id'];
|
||||
}
|
||||
$customfields = $this->contacts->read_customfields($ids);
|
||||
}
|
||||
foreach($datas as $n => $nul)
|
||||
{
|
||||
$data =& $datas[$n]; // $n => &$data is php5 ;-)
|
||||
|
||||
if ($customfields && isset($customfields[$data['id']]))
|
||||
{
|
||||
foreach($customfields[$data['id']] as $name => $value)
|
||||
{
|
||||
$data['#'.$name] = $value;
|
||||
}
|
||||
}
|
||||
// remove empty or null elements, they dont need to be transfered
|
||||
$data = array_diff($data,array('',null));
|
||||
|
||||
// translate birthday to a iso8601 date
|
||||
if(isset($data['bday']) && $data['bday'])
|
||||
{
|
||||
$y = $m = $d = null;
|
||||
list($y,$m,$d) = explode('-',$data['bday']);
|
||||
if (is_null($d)) list($m,$d,$y) = explode('/',$data['bday']);
|
||||
$data['bday'] = $GLOBALS['server']->date2iso8601(array('year'=>$y,'month'=>$m,'mday'=>$d));
|
||||
}
|
||||
// translate timestamps
|
||||
foreach($this->contacts->timestamps as $name)
|
||||
{
|
||||
if(isset($data[$name]))
|
||||
{
|
||||
$data[$name] = $GLOBALS['server']->date2iso8601($data[$name]);
|
||||
}
|
||||
}
|
||||
// translate categories-id-list to array with id-name pairs
|
||||
if(isset($data['cat_id']))
|
||||
{
|
||||
$data['cat_id'] = $GLOBALS['server']->cats2xmlrpc(explode(',',$data['cat_id']));
|
||||
}
|
||||
// replacing the fieldname in tel_prefer with the actual number, if it exists and is non-empty
|
||||
if (substr($data['tel_prefer'],0,4) === 'tel_' && $data[$data['tel_prefer']])
|
||||
{
|
||||
$data['tel_prefer'] = $data[$data['tel_prefer']];
|
||||
}
|
||||
// translate fieldnames if required
|
||||
foreach($this->mapping as $from => $to)
|
||||
{
|
||||
switch($from)
|
||||
{
|
||||
case 'grants[owner]':
|
||||
$data[$to] = $this->contacts->grants[$data['owner']];
|
||||
break;
|
||||
|
||||
case 'private':
|
||||
$data[$to] = $data['private'] ? 'private' : 'public';
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($to{0} == "'") // constant value enclosed in single quotes
|
||||
{
|
||||
$data[$from] = substr($to,1,-1);
|
||||
}
|
||||
elseif(isset($data[$from]))
|
||||
{
|
||||
if ($to) $data[$to] =& $data[$from];
|
||||
unset($data[$from]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* retranslate from xmlrpc / iso8601 to internal format
|
||||
*
|
||||
* @internal
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
function xmlrpc2data($data)
|
||||
{
|
||||
// translate fieldnames if required
|
||||
foreach($this->mapping as $to => $from)
|
||||
{
|
||||
if ($from && isset($data[$from]))
|
||||
{
|
||||
switch($to)
|
||||
{
|
||||
case 'private':
|
||||
$data[$to] = $data['access'] == 'private';
|
||||
break;
|
||||
|
||||
default:
|
||||
$data[$to] =& $data[$from]; unset($data[$from]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// translate birthday
|
||||
if(isset($data['bday']))
|
||||
{
|
||||
$arr = $GLOBALS['server']->iso86012date($data['bday']);
|
||||
$data['bday'] = $arr['year'] && $arr['month'] && $arr['mday'] ? sprintf('%04d-%02d-%02d',$arr['year'],$arr['month'],$arr['mday']) : null;
|
||||
}
|
||||
// translate timestamps
|
||||
foreach($this->contacts->timestamps as $name)
|
||||
{
|
||||
if(isset($data[$name]))
|
||||
{
|
||||
$data[$name] = $GLOBALS['server']->date2iso8601($data[$name]);
|
||||
}
|
||||
}
|
||||
// translate cats
|
||||
if(isset($data['cat_id']))
|
||||
{
|
||||
$cats = $GLOBALS['server']->xmlrpc2cats($data['cat_id']);
|
||||
$data['cat_id'] = count($cats) > 1 ? ','.implode(',',$cats).',' : (int)$cats[0];
|
||||
}
|
||||
// replacing the number in tel_prefer with the fieldname, if it matches a phone-number, otherwise keep it's content as is
|
||||
if ($data['tel_prefer'])
|
||||
{
|
||||
$prefer = $data['tel_prefer'];
|
||||
unset($data['tel_prefer']);
|
||||
if (($key = array_search($prefer,$data)) !== false && substr($key,0,4) === 'tel_')
|
||||
{
|
||||
$data['tel_prefer'] = $key;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['tel_prefer'] = $prefer;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the addressbook
|
||||
*
|
||||
* Todo: use contacts::search and all it's possebilities instead of the depricated contacts::old_read()
|
||||
*
|
||||
* @param array $param
|
||||
* @param int $param['start']=0 starting number of the range, if $param['limit'] != 0
|
||||
* @param int $param['limit']=0 max. number of entries to return, 0=all
|
||||
* @param array $param['fields']=null fields to return or null for all stock fields, fields are in the values (!)
|
||||
* @param string $param['query']='' search pattern or '' for none
|
||||
* @param string $param['filter']='' filters with syntax like <name>=<value>,<name2>=<value2>,<name3>=!'' for not empty
|
||||
* @param string $param['sort']='' sorting: ASC or DESC
|
||||
* @param string $param['order']='' column to order, default ('') n_family,n_given,email ASC
|
||||
* @param int $param['lastmod']=-1 return only values modified after given timestamp, default (-1) return all
|
||||
* @param string $param['cquery']='' return only entries starting with given character, default ('') all
|
||||
* @param string $param['customfields']=true return the customfields too, default yes
|
||||
* @return array of contacts
|
||||
*/
|
||||
function search($param)
|
||||
{
|
||||
$read_customfields = !isset($param['customfields']) || $param['customfields'];
|
||||
|
||||
$extra_accounts = array();
|
||||
if ($this->user_agent == 'KDE-AddressBook' && strpos($this->contacts->contact_repository,$this->contacts->account_repository) === false)
|
||||
{
|
||||
$extra_accounts = $this->contacts->search(array(),false,'','','',false,'AND',false,array(
|
||||
'contact_owner' => 0,
|
||||
));
|
||||
}
|
||||
$searchResults = $this->contacts->old_read(
|
||||
(int) $param['start'],
|
||||
(int) $param['limit'],
|
||||
$param['fields'],
|
||||
$param['query'],
|
||||
$param['filter'],
|
||||
$param['sort'],
|
||||
$param['order'],
|
||||
$param['lastmod'] ? $param['lastmod'] : -1,
|
||||
$param['cquery']
|
||||
);
|
||||
if (!is_array($searchResults)) $searchResults = array();
|
||||
|
||||
return $this->data2xmlrpc(array_merge($searchResults,$extra_accounts),$read_customfields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one contact
|
||||
*
|
||||
* @param mixed $id $id, $id[0] or $id['id'] contains the id of the contact
|
||||
* @return array contact
|
||||
*/
|
||||
function read($id)
|
||||
{
|
||||
if(is_array($id)) $id = isset($id[0]) ? $id[0] : $id['id'];
|
||||
|
||||
$data = $this->contacts->read($id);
|
||||
|
||||
if($data !== false) // permission denied
|
||||
{
|
||||
$data = $this->data2xmlrpc(array($data));
|
||||
|
||||
return $data[0];
|
||||
}
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a contact
|
||||
*
|
||||
* @param array $data
|
||||
* @return int new contact_id
|
||||
*/
|
||||
function save($data)
|
||||
{
|
||||
$data = $this->xmlrpc2data($data);
|
||||
|
||||
$id = $this->contacts->save($data);
|
||||
|
||||
if($id) return $id;
|
||||
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a contact
|
||||
*
|
||||
* @param mixed $id $id, $id[0] or $id['id'] contains the id of the contact
|
||||
* @param boolean true
|
||||
*/
|
||||
function delete($id)
|
||||
{
|
||||
if(is_array($id)) $id = isset($id[0]) ? $id[0] : $id['id'];
|
||||
|
||||
if ($this->contacts->delete($id))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
|
||||
/**
|
||||
* return all addressbook categories
|
||||
*
|
||||
* @param boolean $complete complete cat-array or just the name
|
||||
* @param array with cat_id => name or cat_id => cat-array pairs
|
||||
*/
|
||||
function categories($complete = False)
|
||||
{
|
||||
return $GLOBALS['server']->categories($complete);
|
||||
}
|
||||
|
||||
/**
|
||||
* get or set addressbook customfields
|
||||
*
|
||||
* @param array $new_fields=null
|
||||
* @return array
|
||||
*/
|
||||
function customfields($new_fields=null)
|
||||
{
|
||||
if(is_array($new_fields) && count($new_fields))
|
||||
{
|
||||
if(!$GLOBALS['egw_info']['user']['apps']['admin'])
|
||||
{
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
require_once(EGW_INCLUDE_ROOT.'/admin/inc/class.customfields.inc.php');
|
||||
$fields = new customfields('addressbook');
|
||||
|
||||
foreach($new_fields as $new)
|
||||
{
|
||||
if (!is_array($new))
|
||||
{
|
||||
$new = array('name' => $new);
|
||||
}
|
||||
$fields->create_field(array('fields' => $new));
|
||||
}
|
||||
}
|
||||
$customfields = array();
|
||||
foreach($this->contacts->customfields as $name => $data)
|
||||
{
|
||||
$customfields[$name] = $data['label'];
|
||||
}
|
||||
return $customfields;
|
||||
}
|
||||
}
|
@ -1,341 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* eGroupWare - Calendar's XMLRPC or SOAP access
|
||||
*
|
||||
* Please note: dont use addressbook_... naming convention, as it would break the existing xmlrpc clients
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @package calendar
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2005-8 by RalfBecker-At-outdoor-training.de
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to access AND manipulate calendar data via XMLRPC or SOAP
|
||||
*
|
||||
* eGW's xmlrpc interface is documented at http://egroupware.org/wiki/xmlrpc
|
||||
*
|
||||
* @link http://egroupware.org/wiki/xmlrpc
|
||||
*/
|
||||
class bocalendar
|
||||
{
|
||||
var $xmlrpc_date_format = 'Y-m-d\\TH:i:s';
|
||||
var $debug = false; // log function call to the apache error_log
|
||||
var $cal;
|
||||
var $public_functions = Array(
|
||||
'read' => True,
|
||||
'delete' => True,
|
||||
'write' => True,
|
||||
'search' => True,
|
||||
'categories'=> True,
|
||||
'list_methods' => True,
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->cal = new calendar_boupdate();
|
||||
|
||||
if (is_object($GLOBALS['server']) && $GLOBALS['server']->simpledate)
|
||||
{
|
||||
$this->xmlrpc_date_format = 'Ymd\\TH:i:s';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param string/array $_type string or array with key 'type' for type of interface: xmlrpc or soap
|
||||
* @return array
|
||||
*/
|
||||
function list_methods($_type='xmlrpc')
|
||||
{
|
||||
switch(is_array($_type) ? ($_type['type'] ? $_type['type'] : $_type[0]) : $_type)
|
||||
{
|
||||
case 'xmlrpc':
|
||||
return array(
|
||||
'list_methods' => array(
|
||||
'function' => 'list_methods',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcString)),
|
||||
'docstring' => 'Read this list of methods.'
|
||||
),
|
||||
'read' => array(
|
||||
'function' => 'read',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcInt)),
|
||||
'docstring' => 'Read a single entry by passing the id or uid.'
|
||||
),
|
||||
'write' => array(
|
||||
'function' => 'write',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => 'Add or update a single entry by passing the fields.'
|
||||
),
|
||||
'delete' => array(
|
||||
'function' => 'delete',
|
||||
'signature' => array(array(xmlrpcInt,xmlrpcInt)),
|
||||
'docstring' => 'Delete a single entry by passing the id.'
|
||||
),
|
||||
'search' => array(
|
||||
'function' => 'search',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => 'Read a list of entries.'
|
||||
),
|
||||
'categories' => array(
|
||||
'function' => 'categories',
|
||||
'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
|
||||
'docstring' => 'List all categories.'
|
||||
),
|
||||
);
|
||||
|
||||
case 'soap':
|
||||
return Array(
|
||||
'read' => Array(
|
||||
'in' => Array('int'),
|
||||
'out' => Array('SOAPStruct')
|
||||
),
|
||||
'delete' => Array(
|
||||
'in' => Array('int'),
|
||||
'out' => Array('int')
|
||||
),
|
||||
'write' => Array(
|
||||
'in' => Array('array'),
|
||||
'out' => Array('array')
|
||||
),
|
||||
'search' => Array(
|
||||
'in' => Array('struct'),
|
||||
'out' => Array('SOAPStruct')
|
||||
),
|
||||
'categories' => array(
|
||||
'in' => array('bool'),
|
||||
'out' => array('array')
|
||||
),
|
||||
);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single entry
|
||||
*
|
||||
* @param int/array $id
|
||||
* @return array with event(s) or XMLRPC error not_existent or no_access
|
||||
*/
|
||||
function read($id)
|
||||
{
|
||||
if ($this->debug) error_log('bocalendar::read('.print_r($id,true).')');
|
||||
|
||||
$events =& $this->cal->read($id,null,true,$this->xmlrpc_date_format); // true = ignore acl!!!
|
||||
|
||||
if (!$events) // only id not found, as ignore_acl=true
|
||||
{
|
||||
// xmlrpc_error does NOT return
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_existent'],$GLOBALS['xmlrpcstr']['not_existent']);
|
||||
}
|
||||
if (is_array($id) && count($id) > 1)
|
||||
{
|
||||
foreach($events as $key => $event)
|
||||
{
|
||||
if (!$this->cal->check_perms(EGW_ACL_READ,$event,0,$this->xmlrpc_date_format))
|
||||
{
|
||||
// xmlrpc_error does NOT return
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
$events[$key] = $this->xmlrpc_prepare($event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// for a single id the event is returned and not an array with the event
|
||||
if (is_array($id)) $events = array_shift($events);
|
||||
|
||||
if (!$this->cal->check_perms(EGW_ACL_READ,$events,0,$this->xmlrpc_date_format))
|
||||
{
|
||||
// xmlrpc_error does NOT return
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
$events = $this->xmlrpc_prepare($events);
|
||||
}
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an event
|
||||
*
|
||||
* @param array $ids event-id(s)
|
||||
* @return boolean true or XMLRPC error not_existent or no_access
|
||||
*/
|
||||
function delete($ids)
|
||||
{
|
||||
if ($this->debug) error_log('bocalendar::delete('.print_r($ids,true).')');
|
||||
|
||||
foreach((array) $ids as $id)
|
||||
{
|
||||
if (!$event = $this->cal->read($id,null,true)) // id not found, as ignore_acl=true
|
||||
{
|
||||
// xmlrpc_error does NOT return
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_existent'],$GLOBALS['xmlrpcstr']['not_existent']);
|
||||
}
|
||||
if (!$this->cal->check_perms(EGW_ACL_DELETE,$event))
|
||||
{
|
||||
// xmlrpc_error does NOT return
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
if (!$this->cal->delete($id))
|
||||
{
|
||||
return false; // other db-problem
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add/update an event
|
||||
*
|
||||
* @param array $event event-data
|
||||
* @return int cal-id
|
||||
*/
|
||||
function write($event)
|
||||
{
|
||||
if ($this->debug) error_log('bocalendar::write('.print_r($event,true).')');
|
||||
|
||||
// convert xmlrpc specific values back
|
||||
$event['category'] = $event['category'] ? $GLOBALS['server']->xmlrpc2cats($event['category']) : null;
|
||||
|
||||
// using access={public|private} in all modules via xmlrpc
|
||||
$event['public'] = $event['access'] != 'private';
|
||||
unset($event['access']);
|
||||
|
||||
if (is_array($event['participants']))
|
||||
{
|
||||
foreach($event['participants'] as $user => $data)
|
||||
{
|
||||
if (!is_numeric($user))
|
||||
{
|
||||
unset($event['participants'][$user]);
|
||||
$user = $GLOBALS['egw']->accounts->name2id($data['email'],'account_email');
|
||||
}
|
||||
if (!$user) continue;
|
||||
|
||||
$event['participants'][$user] = in_array($data['status'],array('U','A','R','T')) ? $data['status'] : 'U';
|
||||
}
|
||||
}
|
||||
if (!is_array($event['participants']) || !count($event['participants']))
|
||||
{
|
||||
$event['participants'] = array($GLOBALS['egw_info']['user']['account_id'] => 'A');
|
||||
}
|
||||
if (!($id = $this->cal->update($event,true))) // true=no conflict check for now
|
||||
{
|
||||
$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
|
||||
}
|
||||
return (int) $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* search calendar for events
|
||||
*
|
||||
* If daywise is not set or false, an XMLRPC array of events is returned, otherwise an
|
||||
* XMLRCP struct with date as string (eg. '20060101') and an array of events is returned.
|
||||
*
|
||||
* @param array $params following keys are allowed: start, end, user (more see bocal::search)
|
||||
* @return array with events
|
||||
*/
|
||||
function search($params)
|
||||
{
|
||||
if ($this->debug) error_log('bocalendar::search('.print_r($params,true).')');
|
||||
|
||||
// some defaults for xmlrpc
|
||||
if (!isset($params['date_format'])) $params['date_format'] = $this->xmlrpc_date_format;
|
||||
if (!isset($params['enum_recuring'])) $params['enum_recuring'] = false;
|
||||
// security precausion
|
||||
unset($params['ignore_acl']);
|
||||
|
||||
$events =& $this->cal->search($params);
|
||||
|
||||
foreach($events as $key => $event)
|
||||
{
|
||||
$events[$key] = $this->xmlrpc_prepare($event);
|
||||
}
|
||||
return !$params['daywise'] ? array_values($events) : $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare regular event-array (already with iso8601 dates) to be send by xmlrpc
|
||||
* - participants are send as struct/array with keys: name, email, status
|
||||
* - categories are send as array with cat_id - title pairs
|
||||
* - public is transformed to access={public|private}
|
||||
* - new (1.2) values get unset (eg. participant_types)
|
||||
*
|
||||
* @param array &$event
|
||||
* @return array
|
||||
*/
|
||||
function xmlrpc_prepare(&$event)
|
||||
{
|
||||
$event['rights'] = $this->cal->grants[$event['owner']];
|
||||
|
||||
static $user_cache = array();
|
||||
|
||||
foreach((array) $event['participants'] as $uid => $status)
|
||||
{
|
||||
if (!is_numeric($uid)) continue; // resources
|
||||
|
||||
if (!isset($user_cache[$uid]))
|
||||
{
|
||||
$user_cache[$uid] = array(
|
||||
'name' => $GLOBALS['egw']->common->grab_owner_name($uid),
|
||||
'email' => $GLOBALS['egw']->accounts->id2name($uid,'account_email')
|
||||
);
|
||||
}
|
||||
$event['participants'][$uid] = $user_cache[$uid] + array(
|
||||
'status' => $status,
|
||||
);
|
||||
}
|
||||
if (is_array($event['alarm']))
|
||||
{
|
||||
foreach($event['alarm'] as $id => $alarm)
|
||||
{
|
||||
if ($alarm['owner'] != $GLOBALS['egw_info']['user']['account_id'])
|
||||
{
|
||||
unset($event['alarm'][$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($event['category'])
|
||||
{
|
||||
$event['category'] = $GLOBALS['server']->cats2xmlrpc(explode(',',$event['category']));
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($event['category']);
|
||||
}
|
||||
// using access={public|private} in all modules via xmlrpc
|
||||
$event['access'] = $event['public'] ? 'public' : 'private';
|
||||
|
||||
// unset everything not known in version 1.0
|
||||
foreach(array('public','participant_types') as $key)
|
||||
{
|
||||
unset($event[$key]);
|
||||
}
|
||||
// unsetting everything which could result in an typeless <value />
|
||||
foreach($event as $key => $value)
|
||||
{
|
||||
if (is_null($value) || is_array($value) && !$value)
|
||||
{
|
||||
unset($event[$key]);
|
||||
}
|
||||
}
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* return array with all categories
|
||||
*
|
||||
* @param boolean $complete=false false: return id => title pairs, true array with full data instead of title
|
||||
* @return array
|
||||
*/
|
||||
function categories($complete = False)
|
||||
{
|
||||
return $GLOBALS['server']->categories($complete);
|
||||
}
|
||||
}
|
@ -1,317 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* InfoLog - xmlrpc access
|
||||
*
|
||||
* Please note: dont use infolog_... naming convention, as it would break the existing xmlrpc clients
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @package infolog
|
||||
* @copyright (c) 2003-8 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @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($data))
|
||||
{
|
||||
$delete_children = $data['delete_children'];
|
||||
$new_parent = $data['new_parent'];
|
||||
$info_id = (int)(isset($data[0]) ? $data[0] : $data['info_id']);
|
||||
$status = parent::delete($info_id,$delete_children,$new_parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
$status = parent::delete($data);
|
||||
}
|
||||
|
||||
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 $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 "<p>boinfolog::search(".print_r($query,True).")</p>\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 "<p>boinfolog::search(".print_r($query,True).")=<pre>".print_r($ret,True)."</pre>\n";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an InfoLog entry into its xmlrpc representation, eg. convert timestamps to datetime.iso8601
|
||||
*
|
||||
* @param array $data infolog entry in db format
|
||||
*
|
||||
* @return 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 <value />
|
||||
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 in xmlrpc representation
|
||||
*
|
||||
* @return array infolog entry in db format
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user