Jun 18

Del.icio.us, el archiconocido servicio de gestión de marcadores sociales, ofrece una API para poder desarrollar aplicaciones que utilicen sus servicios. Hace tiempo que vi aparecer la clase Services_Delicious en el repositorio de las PEAR pero hasta ahora no le había podido pegar un ojo, es una clase que implementa un cliente para los servicios web basados en REST de del.icio.us.

La Transferencia de Estado Representacional (Representational State Transfer) o REST describe una interfaz web simple utilizando peticiones HTTP y datos XML pero sin capas adicionales como SOAP, frecuentemente usadas en los servicios web. Precisamente el otro día estuve charlando con mi colega Manuel Aguilar acerca de las ventajas de usar servicios REST en muchos escenarios frente a los clásicos servicios web basados en SOAP o basados en protocolos propios, tema que se trato en la pasada PHP Conference 2007 spring edition celebrada en Stuttgart a la que Manuel asistió.

Sin ánimo de entrar en más detalles de lo que es REST (puedes consultar la definición de la wikipedia que enlazo, está muy bien) vamos a ver como trabajar con del.icio.us desde PHP usando la clase Services_Delicious.

Services_Delicious es una clase todavía en fase beta que no implementa todo lo que nos ofrece el servicio web de del.icio.us, pero que ya permite hacer todas las operaciones básicas cómodamente, como guardar y borrar enlaces, listar los tags, cambiarles el nombre, etc. Son poco más de 400 lineas bastante bien escritas, aunque en PHP4, donde se utiliza HTTP_Request para realizar las peticiones HTTP y XML_serializer para trabajar con los datos XML.

A continuación describo como hacer una nube de tags de una cuenta determinada de del.icio.us y como guardar un nuevo enlace. Esto son sólo dos ejemplos de utilización de algunas de las funciones que nos proporciona Services_Delicious, puedes ver todas las funciones disponibles en el siguiente listado:

  1. getTags()
  2. renameTag($old, $new)
  3. getDates()
  4. getPosts($tags, $date)
  5. getRecentPosts($tags, $max)
  6. getAllPosts()
  7. addPost($url, $description, $extended, $tags, $date, $shared)
  8. deletePost($url)

Instalación de Services_Delicious

Asumiendo que tenemos las PEAR disponibles lo primero que hemos de hacer es instalar la clase en cuestión:

$ pear install --onlyreqdeps Services_Delicious-beta

Si estamos trabajando con la versión estable de las PEAR, lo más habitual, será necesario añadir “-beta” al nombre del paquete o cambiar la variable de configuración preferred_state. La instalación con el frontend web de las PEAR es igualmente sencilla, lo único a tener en cuenta es que necesita el paquete XML_Serializer que no se instalará automáticamente si tenemos preferred_state=stable ya que también se encuentra en fase beta.

Guardando un enlace en del.icio.us

El código necesario para guardar un enlace es el siguiente:

[php] require_once ‘Services/Delicious.php’;
$username = ‘usuario’;
$password = ‘contraseña’;
$dlc = new Services_Delicious($username, $password);
$enlace = ‘http://www.phpbsd.net/’;
$titulo = ‘PHPBSD.net’;
$desc = ‘Blog de programación PHP’;
$tags = ‘php, programación, webdev’;
$result = $dlc->addPost($enlace, $titulo, $desc, $tags);
if (PEAR::isError($result)) {
die($result->getMessage());
} else {
echo ‘OK’;
} [/php]

Con los nombres de las variables se entiende perfectamente como funciona el tema.

Generando una nube de tags

A continuación una utilización un poco más divertida, generar una nube con todas las etiquetas de una cuenta determinada:

[php] $tags = $dlc->getTags();
foreach ($tags as $key => $value) {
echo ‘‘.$key.’ ‘;
} [/php]

Lo anterior sólo es un ejemplo rápido, dependiendo de la cantidad de etiquetas y enlaces se debería hacer algo más con el font-size. Puedes ver funcionando el anterior código sobre mi cuenta en del.icio.us en este ejemplo de nube de tags.

Con Services_Delicious se ha de tener en cuenta que aunque podemos enviar datos con la clásica codificación iso-8859-1 las respuestas vienen en UTF-8, hemos de trabajar con UTF-8 o usar las funciones utf8_encode() y utf8_decode() según convenga, otra opción es modificar Services_Delicious y cambiar la forma de trabajar con XML_Serializer.

Aplicaciones

Aunque la API es muy sencilla nos permite añadir tags a prácticamente cualquier tipo de aplicación PHP, por ejemplo con el anterior código fácilmente nos curramos un pluguin para WordPress que cada vez que colgamos un post lo guarde en del.icio.us, que permita generar una nube de tags, etc. (si es que todavía no existe). Otro ejemplo es con una aplicación de comercio electrónico con stock online como un supermercado o una web de viajes, podemos hacer un script que recorra la BD de turno guardando todos los productos en del.icio.us y permitiendo trabajar con tags, que los usuarios puedan actualizarlos, generar nubes con ellos, etc.

Si a pesar de disponer de tu aplicación PHP en tus servidores o en tu servicio de hosting te gusta sacarte el trabajo de encima con servicios como FeedBurner para los RSS, Flickr para las imágenes, YouTube para los Vídeos… ¿porque no usar del.icio.us para tus tags?

Trabajar con del.icio.us para los tags de tu web tiene la ventaja de que del.icio.us en si es un buen sistema de promoción, mucha gente anda suscrita a RSS de determinados tags, se busca bastante directamente en del.icio.us, etc., y también tiene su efecto en SEO, cada nuevo tag representa un backlink hacia nosotros desde la página de dicho tag. El inconveniente de trabajar con un tercero está claro, que el usuario se pierda por del.icio.us y no vuelva a nuestra tienda o a nuestro blog, aunque siempre podemos usar del.icio.us y no enlazarlos.

A parte de añadir la dimensión de “tag” a nuestra aplicación otro ejemplo de uso de la API de del.icio.us es acceder a nuestros bookmarks de una forma totalmente personalizada y poder mostrarlos como queramos. Un ejemplo de esto es lo que hace Pau Iglesias en la sección de enlaces de su blog, aunque usando otra clase para acceder a la API de del.icio.us que también está muy bien, de hecho es un proyecto más maduro que Services_Delicious.

Esta otra clase es una modificación del mismo Pau Iglesias de la clase original de Dietrich Ayala, autor de las conocidas NuSOAP. En comparación Services_Delicious me gusta más porque básicamente me gusta trabajar con PEAR y usa XML_Serializer/HTTP_Request que, a parte de que ya me las conozco, hacen que el código sea muy limpio y fácilmente adaptable a tus necesidades, pero si no te gustan las PEAR el proyecto del.icio.us PHP API de Pau Iglesias se merece una ojeada, proporciona más o menos las mismas funcionalidades que Services_Delicious pero con el añadido de un interesante sistema de cache.

Tagged with:
Feb 09

Dado que ya he hecho un post acerca de como realizar peticiones cURL y otro relacionado con el formateo de XML, sólo me falta lo evidente, un post acerca de como leer y trabajar con los datos XML recibidos. Desde que tenemos la versión 5 del PHP disponemos de la extensión SimpleXML la cual nos proporciona una forma muy rápida y fácil de leer datos XML. Si has programado parsers XML usando librerías como expat encontrarás que esta extensión es una auténtica maravilla, aunque como siempre, a costa de consumir más recursos (básicamente más memoria… pero lo vale).

Con SimpleXML consigues muy fácilmente convertir un archivo XML en un objeto. Para representar la estructura de elementos del documento XML se construye un objeto con atributos q pueden contener directamente valores o arrays de objetos q también tendrán más atributos, más arrays de objetos, etc. (el número de arrays de arrays de objetos depende de los niveles de anidación de los elementos). Se puede trabajar con estos objetos como con cualquier otro en PHP.

Se entiende mucho mejor su uso con un ejemplo sencillo. Imaginemos el siguiente documento XML:

[xml]


Hola
Hola, que tal?


Re: Hola
Bien, gracias.

[/xml]

Asumiendo que en $data tenemos el XML a leer con un código PHP como:

[php] $xml = simplexml_load_string($data);
foreach ($xml->mensaje as $mensaje)
echo $mensaje->texto.’ ‘; [/php]

Obtendremos el resultado:

Hola, que tal? Bien, gracias.

SimpleXML nos puede devolver errores de todo tipo, documentos malformados, problemas de encodings, etc. Si estás en un entorno donde sólo te interesan los documentos válidos y quieres descartar el resto resulta útil algo como:

[php] function loadXML($data) {
$xml = @simplexml_load_string($data);
if (!is_object($xml))
throw new Exception(‘Error en la lectura del XML’,1001);
return $xml;
} [/php]

Si queremos volver a obtener el documento XML dado un objeto SimpleXML es tan fácil como:

[php] echo $xml->asXML(); [/php]

En ocasiones tenemos XML con muchos niveles de elementos y se hace especialmente engorroso ir recorriendo con “foreach” todo el documento. En estas situaciones, como en muchas otras, es necesario poder buscar dentro de los XML. Esto lo conseguimos con el soporte XPath que ofrece SimpleXML. Por ejemplo para acceder a todos los elementos “asunto” del ejemplo anterior:

[php] foreach ($xml->xpath(‘//asunto’) as $asunto)
echo $asunto.”\n”; [/php]

Existen dos consideraciones a tener en cuenta con el uso de SimpleXML:

[1] Si quieres acceder a un elemento que tiene un guión “-” en su nombre debes hacerlo así:

[php] foreach ($xml->{‘mensaje-personal’} as $mensaje)
echo $mensaje->texto.’ ‘; [/php]

Si suponemos que en el ejemplo anterior sustituimos “mensaje” por “mensaje-personal”.

[2] Es recomendable hacer cast a string siempre que obtenemos datos de los objetos SimpleXML. En ocasiones (unexpected :) en lugar de devolver directamente el valor de un elemento devuelve otro objeto SimpleXML, se soluciona con:

[php] $texto = (string) $data_o->mensaje[0]->texto; [/php]

Antes de terminar comento otra característica interesante y es que podemos convertir un objeto SimpleXML en un objeto DOM y viceversa usando las funciones simplexml_import_dom() y dom_import_simplexml(), incluso en las últimas versiones del PHP se le han añadido métodos para poder modificar y crear desde cero documentos XML trabajando directamente con el objeto SimpleXML (al estilo DOM).

Tagged with:
Feb 06

Si estamos metidos en la “divertida” tarea de programar intérpretes de protocolos XML nos puede ayudar un poco el paquete XML_Beautifier de las PEAR. Se trata de un embellecedor de código que se encarga de limpiar y dejar leíbles los datos XML.

Normalmente en las transacciones XML los datos se transfieren sin saltos de linea, ni espacios extra, etc. Esto, dependiendo de la complejidad del XML, hace casi imposible la lectura por un humano. La clase XML_Beautifier nos ayudará a separar en distintas líneas, tabular correctamente el código entendiendo los tags, simplificar los comentarios, cambiar mayúsculas por minúsculas, reemplazar caracteres por su entidad HTML, etc. Si no quieres estar copiando constantemente los XML en un navegador para poder leer algo te puede ayudar bastante.

Su uso es el siguiente:

[php] require_once ‘XML/Beautifier.php’;
$fmt = new XML_Beautifier();
$resultado = $fmt->formatString($archivo);
if (PEAR::isError($resultado))
echo $resultado->getMessage(); [/php]

En $archivo tenemos el contenido del archivo XML, por ejemplo la respuesta de una petición cURL, y en $resultado obtendremos el XML formateado. También disponemos de la alternativa a formatString() q es:

[php] $resultado = $fmt->formatFile(‘original.xml’, ‘formateado.xml’); [/php]

Con esto se trabaja sobre archivos en disco y no variables. Dispone de distintas opciones de configuración q nos permitirán fijar el número de espacios de los tabs y demás.

Una advertencia acerca de esta clase… Consume bastante memoria y tiempo para realizar la transformación. Es por esto que si estás soportando muchas transacciones XML es aconsejable sólo usar XML_Beatufier en el momento de leer los XML y no siempre.

Ah! por cierto, de momento está sin maintainer, ten controlado donde la usas pq quizás has de dejar de hacerlo… aunque funciona perfectamente.

Tagged with:
preload preload preload