XML-RPC for phpGroupWare
Written by Joseph Engo <jengo@phpgroupware.org>
Cleaned up by Dave Hall

This document will give you a brief introduction to the new XML-RPC calls to 
phpGroupWare.  The older pure PHP XML-RPC classes where cumbersome, slow, 
and had quite a number of issues with parameters and returns not meeting 
XML-RPC specs.

This document is broken down into 2 main sections, for developers of 
applications in phpGroupWare and developers who are writing applications to 
connect to phpGroupWare via XML-RPC.  Keep in mind, I am not great at writing 
documentation, so this doc is quick and to the point.


For phpGroupWare developers:
Before you can port your applications to utilize the XML-RPC features of 
phpGroupWare, you must follow these rules in order for things to work 
correctly:
- ALL functions must have a return of some type.  This is a rule for XML-RPC 
  in general.  If you are unsure what to use, the simple Boolean value of True
  will work.

- Your class must have an array (described below) showing what functions are 
  made available through XML-RPC.  Only allow functions that the client NEEDS 
  to use.
  
- Your method can NOT print out any direct output.  No HTML, XML, etc.  Errors
  must be reported using xmlrpc_error().

- Do NOT add any redirects within the function.  Header(), 
  $GLOBALS['phpgw']->redirect_link() are not acceptable and can lead to a 
  number of issues.

Each class, needs to have an array describing what methods are made available
in that class.  The required fields are, name and description.  Other values 
might be made a requirement in the future.  The other values, such as developer, 
are recommended.

class bofoo
{
	var $xmlrpc_methods = array();

	function bofoo()
	{
		$this->xmlrpc_methods[] = 
			array(
				'name'		=> 'add'
				'description'	=> 'Add an entry'
		);
	}

	function add()
	{
		return True;
	}
}


Description of the xmlrpc_methods array:
	* name:  Name of method to be called
	* description: brief description of what the method does
	* author: List of authors who wrote the function.
	(More to be added soon)

Error reporting:
xmlrpc_error() is a phpGroupWare API function to report errors that have 
happened during that execution.  The errors returned are errors unless they 
are state change errors.

1001: State change
session expired, server not accepting new connections, server down for 
maintaince, etc.  These aren't show stopper errors, but report that 
calling more methods isn't possible.

1002: Notices
An example of this would be a function not returning a value, or other errors 
that can mean things can continue, but should be fixed.

1003: Warning 
An example of this would be an SQL error, care should be taken with the results.

1004: Error 
Invailed parameters, wrong parameter count, invailed parameter data, 
wrong parameter types, etc.  (Not finished)

1005: PHP error
These are errors generated by PHP, can be anything from parse errors, to 
include failures, calling an undefined function, etc. 


For XML-RPC client side developers:
This is for developers who are writing applications to connect to a 
phpGroupWare server via XML-RPC.  Currently, there isn't a list of all 
the methods available.  The follow is a list to get you started:

Session Methods

system.login
This is generally the first method you need to call.  This will return the 
sessionid and kp3.  It will return a 1001 error if the login failed.  The 
faultString will explain why it failed.  The faultString should always 
be written in English.  Example: Session expired, Access not permited and 
Login failed.

system.logout
This will destroy the current session.  This should always be called once you are 
finished with your session.

Application Methods

Calling application level methods should work as follows:
<application name>.<class>.<method>   Example: messenger.bomessenger.read_inbox

Besides the defined methods, there are also listMethods and describeMethods.  
They are ONLY available in the application you are requesting and have the 
rights to access.  For example messenger.bomessenger.listMethods will not 
list infolog.boinfolog.readIdArray since you aren't accessing infolog.  You 
can ONLY call listMethods for an application you have access to.  (This 
might be subject to change)

Connecting to phpGroupWare
When calling /xmlrpc.php, you will need to pass the sessionid and kp3 using the 
HTTP_AUTH headers.  You can also call it with: 
http://<sessionid>:<kp3>@www.mydomain.com/phpgroupware/xmlrpc.php

The username should be the sessionid, and the password should be kp3.  Both 
are required and will fail if not present.  If kp3 is incorrect, (if they 
have mcrypt / mhash installed and enabled) the session will fail to decrypt.

Passing the sessionid and kp3 to the method will be made available soon as 
another method for XML-RPC libraries which don't support this kind of 
authentication.  (Its not apart of the XML-RPC spec)

With the old XML-RPC classes the user would need to have access to the phpgwapi 
in order to access methods like, phpgwapi.applications.read  This restriction 
has been removed with some exceptions.  The phpGroupWare API is in read only 
mode when accessing it via XML-RPC.  Meaning, creating accounts, adding / 
deleting applications, is not currently available.  This will require 
permission checks from inside the function, rather then outside in the call 
wrapper.  Not all methods are available, and care should be taken each time a 
method is enabled.  The only ones enabled are the ones that are NEEDED to be 
enabled.

General information about the new xmlrpc.php file:
In order to use this, you MUST have the epi xmlrpc libraries installed.  They 
are bundled with newer versions of PHP, but require the --with-xmlrpc option 
enabled at ./configure time.  These libraries are written in C, and are much 
faster then the old pure PHP version.  Not to mention, they are also easier 
to use and work correctly.

xmlrpc_call_wrapper():
I know lots of developers prefer not to use wrappers, but this one is required.
When the function is called, the method name is the first parameter sent.  
Rather then require all developers to have this parameter first, and a single 
array as the actual parameters sent, this will filter and handle it.

Permissions are checked before the method is registered.  If they can't access
an application, the application isn't even registered.  This will also return 
an error stating Access not permitted.

system.login is only registered when there is no sessionid and/or kp3 present.
system.logout is only registered when there is a valied session present.
