Escolha uma Página

Objetivo

Escrever e entender os plugin que recebem as chamadas utilizando XMLRPC, vamos mexer com um cliente e um servidor

Introdução

O XMLRPC é uma tecnologia que permite a você executar métodos do Joomla remotamente a partir de outro aplicativo. Nativamente no joomla já vem instalado com algumas chamadas XMLRPC:

  1. Plugin joomla: fornece o método searchSite permite executar consultas ao conteúdo de um site remotamente;
  2. System: são os métodos nativos do próprio joomla para manipular os demais plugins que executam XMLRPC.

O Joomla utilizar a biblioteca phpxmlrpc, para gerenciar as chamadas XMLRPC, eu aconselho você a também utilizá-la em seus clientes.

Antes de Começar

Antes de começar a codificar vamos configurar no joomla

  1. Acesse as configurações globais
  2. System
  3. Enable Web Services (Habilitar Web Services): marque como Sim
  4. Debug Settings (Debugar Configurações) marque como Sim

A configuração Debug Settings deve apenas ficar ativa no seu ambiente de desenvolvimento, no ambiente de produção ela deve ficar marcada como não.

Debugger

Desenvolver Web Service requer ferramentas de debug mais elaboradas haja visto que os print_r e die causam efeitos estranhos no códgo fonte, sendo assim vou apresentar duas ferramentas de debug.

Debug Nativo

O próprio joomla já fornece um debug para XMLRPC, para o acessar:

  1. Acesse as configurações globais
  2. System
  3. Habilite a opção Debug System

Depois disso acesse:

http://seusite/xmlrpc/client.php

Debug com o Phpxmlrpc

Dentro da pasta do phpxmlrpc existe uma pasta chamada debbuger, para utilizar o debug:  e acesse a pasta debugger, por aqui você pode testar o seu webservice.

  1. Copie o arquivo xmlrpc.inc que está na pasta lib para dentro da pasta debugger
  2. Copie o arquivo xmlrpc_wrappers.inc que está na pasta lib para dentro da pasta debugger
  3. Acesse o endereço http://seusite/debugger/
  4. Configure o campo Address para Endereço do site onde está o seu plugin, exemplo localhost e o campo Path com o caminho APÓS o localhost onde estão os plugins, no caso do joomla é /xmlrpc/index.php.
  5. Escolha uma das ações: List available methods, Describe method, Execute method, Generate stub for method call
  6. Clique no botão executar

Caso você esteja trabalhando com uma instalação nova do Joomla então você terá a disposição os seguintes métodos:

  1. joomla.searchSite
  2. system.listMethods
  3. system.methodHelp
  4. system.methodSignature
  5. system.multicall
  6. system.getCapabilities

Criando um Cliente

Vamos criar um cliente para acessar o método searchSite da classe plgXMLRPCJoomla, o retorno desse método é um vetor um todas as matérias que contenham um determinado texto:

function xmlrpc_joomla_searchSite ($p1, $p2, $debug=0) {
$client =& new xmlrpc_client('/xmlrpc/index.php', 'seu_site_sem_http', 0);
$client->port = 0;
$client->method = 'http';
$client->errno = 0;
port = 0;
$client->method = 'http';
$client->errno = 0;
$client->errstr = '';
$client->authtype = 1;
$client->cert = '';
$client->certpass = '';
$client->cacert = '';
$client->cacertdir = '';
$client->key = '';
$client->keypass = '';
$client->verifypeer = true;
$client->verifyhost = 1;
$client->no_multicall = false;
$client->proxy = '';
$client->proxyport = 0;
$client->proxy_user = '';
$client->proxy_pass = '';
$client->proxy_authtype = 1;
$client->cookies = array (
);
$client->accepted_compression = '';
$client->request_compression = '';
$client->xmlrpc_curl_handle = NULL;
$client->keepalive = true;
$client->accepted_charset_encodings = array (
  0 => 'UTF-8',
  1 => 'ISO-8859-1',
  2 => 'US-ASCII',
);
$client->request_charset_encoding = '';
$client->return_type = 'xmlrpcvals';
$client->setDebug($debug);
$msg =& new xmlrpcmsg('joomla.searchSite');
$p1 =& new xmlrpcval($p1, 'string');
$msg->addparam($p1);
$p2 =& new xmlrpcval($p2, 'string');
$msg->addparam($p2);
$res =& $client->send($msg, 0, '');
if ($res->faultcode()) return $res; else return php_xmlrpc_decode($res->value());
}
 
$result = xmlrpc_joomla_searchSite('Palavra Chave','exact');
 
print_r($result);
die();

Pronto temos o nosso cliente rodando. Todos os plugins devem estar dentro da pasta plugins/xmlrpc o método que estamos executando é o joomla.searchSite ou seja abra o arquivo joomla.php que dentro dele tem a definição deste método.

Este plugin joomla na versão 1.5.14 tem um bug que eu acabei  acertando e mandando para o repositório. http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=18748

Criando o Servidor

A parte do servidor exige atenção pois a partir daqui você estará dando permissão para qualquer pessoa de qualquer lugar do mundo executar algum método então escreva-o com sabedoria:

Vou colar aqui um exemplo do plugin joomla ok:

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.plugin.plugin');

class plgXMLRPCJoomla extends JPlugin
{
	function plgXMLRPCJoomla(& $subject, $config){
		parent::__construct($subject, $config);
	}

	function onGetWebServices(){
		global $xmlrpcString;
		// Initialize variables
		$services = array();
		// Site search service
		$services['joomla.searchSite'] = array( // nome do método que você irá chamar do cliente
			'function' => 'plgXMLRPCJoomlaServices::searchSite', // nome do método que irá executar qnd uma chamada acontecer
			'docstring' => 'Searches a remote site.', // apenas uma descrição
			'signature' => array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString)) // o primeiro parâmetro indica o tipo do retorno e os demais são os parâmetros da função			);
		return $services;
	}
}

class plgXMLRPCJoomlaServices {

	function searchSite($searchword, $phrase='', $order='')
	{
		global $mainframe;

		// Initialize variables
		$db		=& JFactory::getDBO();

		// Prepare arguments
		$searchword	= $db->getEscaped( trim( $searchword ) );
		$phrase		= '';
		$ordering	= '';

		// Load search plugins and fire the onSearch event
		JPluginHelper::importPlugin( 'search' );
		$results = $mainframe->triggerEvent( 'onSearch', array( $searchword, $phrase, $ordering ) );

		// Iterate through results building the return array
		require_once(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_search'.DS.'helpers'.DS.'search.php');

		foreach ($results as $i=>$rows)
		{
			foreach ($rows as $j=>$row) {
				$results[$i][$j]->href = eregi('^(http|https)://', $row->href) ? $row->href : JURI::root().'/'.$row->href;
				$results[$i][$j]->text = SearchHelper::prepareSearchContent( $row->text, 200, $searchword);
			}
		}
		return $results;
	}
}

Algumas dicas sobre o servidor:

  1. Para manter compatibilidade com o php4 não use __construct e sim o nome da classe como sendo o construtor
  2. Após criar o plugin você precisa INSTALAR e ATIVAR antes de fazer qualquer chamada ao plugin caso contrário irá receber uma mensagem de Unknow Method

Observação Importantes

  1. Em ambiente de teste onde você tem o seu cliente e o servidor no MESMO servidor é importante que o servidor conheça o endereço que você está acessando caso contrário vai dar um erro de (An error occurred: Code: 5 Reason: ‘Didn’t receive 200 OK from remote server. (HTTP/1.0 302 Found)’) ou seja, o seu site não foi encontrado, nesse caso adicione o seu ambiente de teste no host da sua máquina servidora.
  2. ‘signature’ => array(array($xmlrpcString, $xmlrpcString, $xmlrpcString)) : Na  assinatura do método o primeiro parâmetro define o tipo do retorno e os demais são os tipos dos parâmetros da função que será chamada

Descrição do Erros

Abaixo tem uma lista dos erros que o RPC pode te retornar

Fault codes for your servers should start at the value indicated by the global $xmlrpcerruser + 1.
Standard errors returned by the server include:
1 Unknown method
Returned if the server was asked to dispatch a method it didn't know about

2 Invalid return payload
This error is actually generated by the client, not server, code, but signifies that a server returned something it couldn't understand. A more detailed error report is sometimes added onto the end of the phrase above.

3 Incorrect parameters
This error is generated when the server has signature(s) defined for a method, and the parameters passed by the client do not match any of signatures.

4 Can't introspect: method unknown
This error is generated by the builtin system.* methods when any kind of introspection is attempted on a method undefined by the server.

5 Didn't receive 200 OK from remote server
This error is generated by the client when a remote server doesn't return HTTP/1.1 200 OK in response to a request. A more detailed error report is added onto the end of the phrase above.

6 No data received from server
This error is generated by the client when a remote server returns HTTP/1.1 200 OK in response to a request, but no response body follows the HTTP headers.

7 No SSL support compiled in
This error is generated by the client when trying to send a request with HTTPS and the CURL extension is not available to PHP.

8 CURL error
This error is generated by the client when trying to send a request with HTTPS and the HTTPS communication fails.

9-14 multicall errors
These errors are generated by the server when something fails inside a system.multicall request.

100- XML parse errors
Returns 100 plus the XML parser error code for the fault that occurred. The faultString returned explains where the parse error was in the incoming XML stream.

Livros

Infelizmente os livros sobre joomla em português não são muitos mas se você quiser dar uma olhada o submarino oferece algumas opção como o  Joomla Guia do Operador, caso queira em inglês eu recomendo o livro Mastering Joomla.

Links Úteis