Auteurs : 
	Ludovic Kiefer (ludovic@skolelinux.fr)
	Jean-Charles Siegel (jeancharles@skolelinux.fr)

Date :
	21 mars 2010

Système :
	debian-edu etch
	debian-edu lenny
	debian-edu squeeze

Communication entre un client et un serveur XML-RPC - CipUX-cat-moodle
----------------------------------------------------------------------

1. Pré-requis

Il faut avoir d'installé le serveur mysql. La dernière version présente dans vos
dépôts sera la bonne.
C'est un méta-paquet appelé "mysql-server".

# aptitude install mysql-server

Il vous sera demandé un mot de passe pour le super utilisateur de mysql.
Installez maintenant les paquets pour php5. A savoir :
  * php5 : paquet de base pour php5
  * php5-mysql : paquet pour la connexion entre php5 et mysql
  * php5-curl : paquet pour activer le cryptage SSL de php

# aptitude install php5 php5-mysql php5-curl

Maintenant vous pouvez installer moodle et le theme Skolelinux (debian-edu) de 
moodle.

# aptitude install moodle moodle-debian-edu-theme

Il vous sera demandé le serveur web à utiliser. Choississez apache2. De même 
vous devrez choisir le serveur de base de données. Comme nous avons installé
mysql, choississez le.

L'adresse demandée pour la connexion à la base de données est par défaut 
localhost. Laissez cette adresse. Par contre il vous sera ensuite demandé de
saisir le nom du super-utilisateur de Mysql (si vous avez choisi mysql), celui-
ci est "root" et le mot de passe est celui que vous avez saisi lors de 
l'installation du serveur Mysql.

Maintenant il faut créer un nom d'utilisateur pour moodle qui servira dans Mysql.
Par défaut celui-ci est "moodle". Laissez-le. Vous devez choisir un mot de passe
pour cet utilisateur, choississez celui qui vous plaît. Normalement vous ne 
devriez plus en avoir besoin.

IL faut évidemment avoir un serveur XML-RPC déjà d'installé, et particulièrement
le serveur CipUX-XML-RPC. (voir avec Christian Külker)

2. Développer un client XML-RPC en PHP pour CipUX

2.1. Le fichier de configuration

/** Server IP address or DNS name */
ifdefine("CIPUX_RPC_HOST","localhost"); 
/** Server TCP Port */
ifdefine("CIPUX_RPC_PORT","8001");
/** Server PATH */
ifdefine("CIPUX_RPC_PATH","/RPC2"); 
/** Should we put plenty of debug lines on stdout ? (default no) */
ifdefine("CIPUX_RPC_DEBUG",2); 
/** Socket timeout in seconds */
ifdefine("CIPUX_RPC_TIMEOUT",10);  
/** Transport can be one of http, https, http11 */
ifdefine("CIPUX_RPC_TRANSPORT","http"); 
/** Cookie name send to the user (if you request for automagic cookie sending) */
ifdefine("CIPUX_RPC_COOKIE_NAME","COOKIE_CIPUX"); 

Il indique où communiquer avec le serveur XML-RPC. Donc ici on communique à 
l'adresse :

	http://localhost:8001/RPC2

2.2. Librairies

Il faut utiliser les librairies xmlrpc.inc et xmlrpcs.inc. Elles contiennent 
toutes les fonctions de bases pour communiquer avec un serveur XML-RPC.

La librairie cipux_xml.class.php est spécialement faite pour communiquer avec un
serveur XML-RPC. Elle est INDISPENSABLE.

2.3. Communication avec le serveur

2.3.1. Construction du fichier xml à envoyer.

On va prendre une fonction toute simple. La fonction PING. 

Extrait du code perl faisant appelle à la fonction PING créée par Chrisitan Külker.
<code perl>

[...]

my $header_hr = {
    cipux_version  => '3.4.0.0',
    client_name    => 'expl_rpc_ping',
    client_version => '0.1',
    rpc_version    => '2.0',
    client_key     => '',
    client_cred    => '',
    gmt_time       => time,
};

my $pay_hr = {
    header_hr => $header_hr,
    login     => 'dummy',
    ticket    => 'dummy',
    cmd       => 'ping',
    param_hr  => {},
};

[...]

eval { $answer_hr = $server->call( 'ping', $pay_hr ); };
</code>

Vous pouvez voir qu'on fait appel au serveur en indiquant quelle fonction (ping)
et en lui passant le paramètre ($pay_hr). Ce dernier est une structure spécifique
à Perl qui est le HASH (en gros un tableau associatif avec un tableau dans un
tableau). 

Il faut recréer cette même structure en PHP.

Pour cela on va créer un tableau associatif. Le header_hr vient en premier :

<code php>
$this->header_hr = array (
	"cipux_version"  => new xmlrpcval('3.4.0.0','string'),
	"client_name"    => new xmlrpcval("cipux_cat_moodle","string"),
	"client_version" => new xmlrpcval("0.1","double"),
	"rpc_version"    => new xmlrpcval("2.0","double"),
	"client_key"     => new xmlrpcval("", "string"),
	"client_cred"    => new xmlrpcval("", "string"),
	"gmt_time"       => new xmlrpcval(time(), "i4")
);
</code>

Vous pouvez constater que le header_hr de Perl et celui de PHP sont assez 
identiques. La différence vient du fait que toutes les valeurs de ce tableau 
doivent être des objets "xmlrpcval" sinon cela ne fonctionne pas.

En plus, il faut spécifier le type de ces valeurs. Par défaut, si le type n'est 
pas précisé, la librairie xmlrpc.inc considère que la valeur est une chaîne de 
caractères (string). Ce header_hr ne changera jamais, il se trouve dans le 
constructeur de la classe cipux_xml. Il ne faut pas le modifier.

Passons à la suite.

Pour chaque fonction qui vont être créées pour cipux_xml, il faut créer un 
payload (pay_hr). Ce payload (regarder le code Perl plus haut) doit contenir le
header_hr (cela revient à faire un tableau imbriqué ou tableau dans un tableau).

<code php>
public function ping () {
	$param_hr = array ();
	$pay_hr = array (
		"header_hr" => new xmlrpcval($this->header_hr, "struct"),
		"login"     => new xmlrpcval("dummy", "string"), // here the login of cipux 
		"ticket"    => new xmlrpcval("dummy", "string"), // here the ticket given at the first login
		"cmd"       => new xmlrpcval("ping", "string"), // here the name of the command
		"param_hr"  => new xmlrpcval($param_hr, "struct") 
	);
	$f = new xmlrpcmsg('ping', array(new xmlrpcval ($pay_hr, "struct")));
	return $this->_standard_call($f);
}
</code> 

Donc on intègre dans le pay_hr le header_hr en tant qu'objet xmlrpc (xmlrpcval) 
et le définir en tant que structure. 

Il y a un deuxième tableau dans cette fonction, qui est param_hr. Ce doit aussi 
être un tableau. Pour d'autre fonction CipUX (somme, creation...), ce tableau 
contiendra les valeurs à passer en paramètres à ces fonctions.

Ici, PING n'a pas besoin de paramètres donc c'est un tableau vide qu'on insère 
en tant qu'objet XML-RPC (xmlrpcval) de type structure (struct).














