Apr 10

Hace tiempo escribí un post acerca de como usar FeedBurner para los feeds de un WordPress que se ha quedado algo obsoleto debido a algunos cambios en WordPress respecto a la URL de los feeds y a la compra de FeedBurner por parte de Google.

Si todavía crees que usar FeedBurner es una buena idea (yo nunca lo tuve claro) la forma más cómoda de configurarlo es modificando el archivo .htaccess, aunque también existen plugins específicos (por ejemplo el FD Feedburner Plugin).

Se trata de añadir lo siguiente al .htaccess:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} !FeedBurner [NC]
RewriteCond %{HTTP_USER_AGENT} !FeedValidator [NC]
RewriteRule ^feed/(.*)$ http://feeds2.feedburner.com/xxxxxx [R,L]
</IfModule>

Con lo anterior conseguimos que nuestro WordPress únicamente genere el feed para FeedBurner y que el resto de clientes (navegadores, arañas, etc.) sean redirigidos a la URL de FeedBurner.

Teóricamente este es el mejor método para usar FeedBurner ya que seguimos difundiendo la URL del feed original y así siempre podemos dejar de usar este servicio sin muchos inconvenientes. El problema está en que al haber la redirección muchos usuarios siguen el enlace del feed con el navegador y se suscriben a la URL del feed de FeedBurner… o sea que con el tiempo acabaremos con lectores suscritos a ambas URLs.

El método alternativo es modificar el theme de WordPress, o usar algún plugin, para difundir directamente la URL del feed de FeedBurner.

Proxy de Google

Si teníamos una cuenta en FeedBurner y la hemos migrado a Google recientemente, a parte del engorroso cambio de la URL del feed, quizás hemos notado que ahora la URL que difunde tu feed para cada post pasa por un proxy de Google.

En principio esto ya sucedía antes y el cambio únicamente es que ahora en lugar de pasar por feeds.feedburner.com pasa por feedproxy.google.com (aunque en mi caso antes de migrar la cuenta a Google no pasaba por ningún proxy, tengo caché, lo puedo demostrar :)

En cualquier caso si queremos desactivar completamente el proxy de Google hemos de cambiar la configuración de nuestro feed en FeedBurner. Concretamente se trata de desactivar la opción “Item link clicks” de la sección “TotalStats” dentro de la pestaña “Analize”. Con esto seguiremos teniendo estadísticas de número de lectores e ítems vistos (información más que suficiente) pero difundiremos siempre la URL original de cada post, algo muy recomendable para SEO (como bien nos explicaba Armonth hace tiempo).

Así es como debería quedar la configuración en FeedBurner:

FeedBurner snapshot

Tagged with:
Apr 02

Desde la llegada de PHP 5.0 disponemos de varios métodos mágicos para nuestras clases PHP, entre ellos tenemos __toString() que nos permite codificar cómo queremos que se comporte una clase cuando una instancia de ella se convierte a un string.

Aunque a simple vista el método __toString() pueda parecer poco importante en PHP éste toma mucha relevancia si trabajamos con symfony o algún otro framework orientado a objetos donde la información de la base datos se encuentra mapeada en un modelo de objetos.

A pesar de que __toString() está disponible desde la versión 5.0.0 del PHP en mi opinión no empieza a ser realmente útil hasta la versión 5.2.0, algo que en el changelog del PHP reflejaron con un tímido:

Changed __toString() to be called wherever applicable. (Marcus)

Hasta entonces __toString() sólo se llamaba cuando se usaba echo() o print() lo que limitaba mucho su funcionalidad. Desde la versión 5.2.0 __toString() se llama siempre que tratemos a un objeto como a un string.

Por ejemplo dada la siguiente definición de clase:

[php] class User extends BaseUser
{
public function __toString()
{
return $this->getName();
}
} [/php]

Hasta PHP 5.2.0 sólo podíamos invocar a __toString() con:

[php] $user = new User();
echo $user;
print $user; [/php]

Desde la versión 5.2.0 podemos hacer varias cosas interesantes con __toString() sobretodo relacionadas con el manejo de arrays de objetos, algo muy frecuente en los frameworks que corren por ahí hoy en día.

Por ejemplo si obtenemos el típico array de objetos con symfony:

[php] $users = UserPeer::doSelect(new Criteria()); [/php]

Trabajando directamente con las funciones de PHP entre otras muchas cosas podemos:

  • Ordenar el array de objetos con un simple sort()
  • Eliminar objetos duplicados del array con un array_unique()
  • Generar una lista separada por comas para la presentación con un implode()
  • Buscar un objeto determinado dentro del array con array_search()

Alternativas a __toString()

Si no tenemos la suerte de trabajar con PHP 5.2.x, o si queremos poder trabajar con un método distinto de __toString() para determinadas operaciones con arrays de objetos, podemos usar un código parecido al que propongo a continuación:

[php] class objectTools
{
protected static function getMethodValues($list, $method)
{
$items = array();
foreach ($list as $key => $obj)
$items[$key] = $obj->$method();
return $items;
}
protected static function getObjectList($items, $list)
{
$ret = array();
foreach ($items as $key => $item)
$ret[] = $list[$key];
return $ret;
}
public static function arraySortByMethod($list, $method, $sort=’desc’)
{
$items = self::getMethodValues($list, $method);
asort($items);
if ($sort==’desc’)
return array_values(array_reverse(self::getObjectList($items, $list)));
return self::getObjectList($items, $list);
}
public static function arrayUniqueByMethod($list, $method)
{
$items = self::getMethodValues($list, $method);
return self::getObjectList(array_unique($items), $list);
}
public static function arrayImplodeByMethod($list, $method, $sep)
{
$items = self::getMethodValues($list, $method);
return implode($sep, $items);
}
public static function arraySearchByMethod($list, $method, $needle)
{
$items = self::getMethodValues($list, $method);
return array_search($needle, $items);
}
} [/php]

Lo anterior es más una propuesta de código que algo decente para ser distribuido. Simplemente se trata de trabajar con un array temporal para almacenar los valores del método solicitado, correr la función PHP y, si es necesario, volver a construir el array de objetos.

Algunos ejemplos de uso:

[php] $ordenados = objectTools::arraySortByMethod($users, ‘getName’, ‘asc’);
$sin_duplicados = objectTools::arrayUniqueByMethod($users, ‘getName’);
$pos = objectTools::arraySearchByMethod($users, ‘getName’, ‘oriol’);
//y por último en una plantilla…
echo ‘Usuarios: ‘ . objectTools::arrayImplodeByMethod($users, ‘getName’, ‘, ‘); [/php]

Fácilmente se pueden añadir tantos métodos de tratamiento de arrays como se necesiten… o mucho mejor hacer un método que simplemente reciba como variable la función PHP a ejecutar. En mi caso de momento sólo necesito estos en concreto y también así los puedo controlar individualmente.

Aunque estos métodos de objectTools nacieron como “parche” rápido dado que no tenía PHP 5.2.x para un proyecto symfony, ahora, una vez solventando el problema con los servidores, los sigo encontrando útiles en múltiples situaciones. Por supuesto se ha de tener presente el poco rendimiento de este código frente a realizar queries a medida usando el objeto Criteria, pero si ya tenemos un array de objetos en memoria sí que será más óptimo trabajar con él en lugar de lanzar varias queries contra la base de datos.

Tagged with:
Feb 22

Desde hace muchos años y por mucho que evolucione el desarrollo web e internet el SSH, al igual que el CVS/SVN, sigue siendo una de las herramientas más usada para administrar aplicaciones web y sus respectivos servidores.

Una de las funciones que para mi resulta más útil del SSH a parte de lo evidente que es poder iniciar sesión en nuestro servidor, es poder ejecutar comandos remotamente y así fácilmente poder escribir scripts (PHP y/o de shell) que interactúen entre máquinas. Por ejemplo para subir la última release de nuestra web a producción, borrar cachés de disco, reiniciar algún que otro Apache que se ha quedado tonto, etc.

Algo que resulta muy útil en estos casos es poder usar SSH entre distintas máquinas sin necesidad de ir introduciendo la contraseña. Para conseguirlo, y entendiendo bien el riesgo de seguridad que puede suponer, hemos de seguir los siguientes pasos:

[1] Iniciamos sesión en el servidor A con el usuario que queremos dejar libre de contraseña y ejecutamos:

$ ssh-keygen -t rsa

[2] Añadimos la clave publica generada (.ssh/id_rsa.pub) al archivo de claves aceptadas del servidor B, por ejemplo vía SCP:

$ scp .ssh/id_rsa.pub usuario@B:.ssh/authorized_keys

Se ha de tener en cuenta que el anterior comando sobreescribe el archivo y podemos tener más de una clave aceptada en authorized_keys.

[3] Listos! Desde el servidor A ya podemos entrar en B sin contraseña. Si estamos logueados con el usuario correcto sólo será necesario ejecutar:

$ ssh B

Al programar en PHP por supuesto que siempre tienes la alternativa de realizarlo todo vía peticiones HTTP aunque para determinadas tareas y situaciones los scripts CLI son una gran alternativa (y los puedes hacer muy chulos usando ncurses).

Tagged with:
Feb 21

Es un procedimiento muy sencillo que está perfectamente detallado en la documentación de WordPress aunque quizás faltan un par de puntos por explicar un poco mejor.

Si nuestra intención es hacer borrón y cuenta nueva con nuestro blog eliminando todos los archivos pero conservando la base de datos los pasos a seguir son los siguientes:

[1] Como siempre antes de empezar cualquier tarea parecida backup de todo. Incluso es buena idea montar el blog entero en otro sitio para después poder comparar el viejo con el nuevo.

[2] Desactivamos todos los plugins y seleccionamos el tema por defecto. Aunque en nuestro caso como tenemos intención de borrar todos los archivos el nuevo WordPress desactivará todo lo que no encuentre.

[3] Borramos todos los archivos anteriores. Si tenemos el wordpress mezclado con otras cosas el comando en cuestión es algo como:

$ rm -rf index.php license.txt readme.html wp-* xmlrpc.php

[4] Descomprimimos la última versión de WordPress en el mismo sitio donde teníamos la anterior.

[5] Editamos el nuevo wp-config.php y añadimos los datos de conexión y nombre de la BD.

[6] Comprobamos en qué codificación está trabajando nuestro WordPress. Por ejemplo con:

mysql> show create table wp_posts;

Nos fijamos en el CHARSET utilizado y definimos DB_CHARSET con el mismo valor. En el caso de ser “utf8” no tenemos que tocar nada pero si estamos con “latin1” es necesario indicarlo en wp-config.php con:

[php] define(‘DB_CHARSET’, ‘latin1’); [/php]

[7] Iniciamos el programa de actualización apuntando el navegador a la URL habitual del dashborad (p.e. http://tublog.es/wp-admin/)

[8] Automáticamente aparecerá un mensaje diciendo que debemos proceder con la actualización de la BD. Hacemos clic en “Siguiente” y cruzamos los dedos… si todo va bien te aparecerá algo como “Update successful”.

[9] WordPress casi actualizado!

Digo casi porque casi seguro vamos a necesitar realizar alguno de lo siguientes pasos adicionales:

  • Si habíamos subido archivos al WordPress utilizando su dashboard hemos de copiar la anterior carpeta wp-content/uploads a la nueva instalación.
  • Si trabajábamos con algún plugin para los tags debemos lanzar la importación manualmente desde el dashboard, por ejemplo en el caso del UTW desde “Herramientas” -> “Importar” -> “Ultimate Tag Warrior”.
  • Si ha pasado mucho tiempo desde la última actualización no es mala idea repasarse las opciones de configuración de WordPress y comprobar que todo está ok, especialmente la sección de Permalinks.
  • Como hemos empezado de nuevo en lo que a código PHP se refiere es necesario volver a instalar los plugins que echemos en falta y un tema que nos guste. Por supuesto descargando las últimas versiones de todo y no aprovechando nada del anterior WP para así sacar el máximo partido de las nuevas funcionalidades (en parte uno de los objetivos del procedimiento descrito en este post).
Tagged with:
Jan 29

HTML Purifier es una librería para filtrar HTML escrita en PHP que permite eliminar el código malicioso (XSS) a la vez que comprueba que el HTML valide contra el estándar correspondiente.

Una de las principales diferencias de HTML Purifier comparada con otras librerías de filtrado HTML es que descompone por completo el HTML y verifica que cada uno de los elementos se encuentre dentro de una whitelist de elementos permitidos en lugar de limitarse a buscar elementos prohibidos en una blacklist (normalmente desfasada). A la vez que elimina el código no deseado también hace algo poco común en librerías de este tipo, valida que el HTML cumpla el estándar correspondiente y si no lo cumple realiza las modificaciones necesarias para corregirlo.

Puedes usar HTML Purifier tanto para filtrar datos de entrada, en el caso de que sea posible recibir código HTML, como el HTML de salida de tu aplicación. Lo más frecuente es usarla para filtrar datos de entrada como comentarios, emails, el resultado de algunos editores WYSIWYG, etc.

Se ha de tener presente que dado su funcionamiento interno es una librería muy potente pero pesada y lenta, no es para nada recomendable filtrar la salida de tu aplicación cada vez que generas código HTML. Mucho mejor filtrar la entrada y asegurar que el contenido de tu sistema está limpio. En todo caso para filtrar la salida se convierte en algo obligatorio trabajar con algún sistema de cache (generar páginas estáticas, un reverse proxy, en BD capturando el output-buffer, etc.)

A continuación explico brevemente su instalación y uso.

Instalación

[1] Descargar el archivo htmlpurifier-3.0.0.tar.gz y descomprimirlo en el servidor. No es necesario que esté accesible para los usuarios, puedes colocarlo fuera del DocumentRoot. Ten en cuenta que la última versión (la 3.0) sólo es compatible con PHP5.

[2] Poner los permisos adecuados a los directorios que HTML Purifier usará para cachear algunos archivos. Los directorios en cuestión son DefinitionCache/Serializer y todos sus subdirectorios. Si tenemos acceso por shell al servidor lo solucionamos con un:

chmod -R 0777 HTMLPurifier/DefinitionCache/Serializer

Utiliza 0777 o 0775 según convenga, el objetivo es permitir al servidor web escribir en estos directorios.

[3] Es necesario tener instalada la extensión iconv si quieres trabajar con un enconding distinto de UTF-8 y si quieres una salida más bonita del HTML también es necesaria la extensión tidy.

[4] Para mayor comodidad puedes incluir el directorio de la HTML Purifier en tu include_path a pesar de que es recomendable sólo hacer require() cuando vayas a usarla, es una librería bastante grande.

Usando la librería

[php] $dirty_html = ‘prueba’;
require_once ‘/directorio_de_htmlpurifier/library/HTMLPurifier.auto.php’;
//require_once ‘HTMLPurifier.php’;
$config = HTMLPurifier_Config::createDefault();
$config->set(‘Core’, ‘Encoding’, ‘ISO-8859-1’);
$config->set(‘HTML’, ‘Doctype’, ‘HTML 4.01 Transitional’);
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);
echo $clean_html; [/php]

En el ejemplo se incluye el archivo HTMLPurifier.auto.php indicando la ruta completa, si has añadido el directorio de la librería en tu include_path puedes incluir HTMLPurifier.php directamente (usa la línea comentada).

En este ejemplo simple se está configurando HTML Purifier para que trabaje con ‘HTML 4.01 Transitional’ codificado en ‘ISO-8859-1’. Por defecto la librería trabaja con ‘XHTML 1.0 Transitional’ en ‘UTF-8’, si este es el único tipo de documento y codificación que necesitas puedes eliminar las llamadas a set() y no es necesario crear el objeto $config. Existen muchos otros parámetros de configuración que se merecen una ojeada aunque para un funcionamiento normal no es necesario tocar casi nada.

También existen plugins para varios CMS conocidos para empezar a usar HTML Purifier de una forma todavía más fácil. Entre ellos está el plugin HTML Purified para WordPress y el módulo HTML Purifier para Drupal.

Tagged with:
preload preload preload