Archive for the ‘desarrollo web’ Category

Developer facts

17 diciembre 2010

A veces a uno le de por pensar en por qué fallan tanto los desarrollos de software (así, en general). Es evidente que las razones son, por decir un número, mogollón. Pero como hoy tocaba hacer un poco de autocrítica, charlando con los compis en el café nos han venido a la cabeza unos cuantos vicios clásicos de los programadores. Esas situaciones que se repiten en cada proyecto, cual Sísifo cargando con su piedra montaña arriba. Ahí van:

Error 500: System failure

  • Lo que hizo el programador anterior es una mierda. Es mejor empezar de cero.
  • Mi religión es internet y mi Padre Nuestro es el copy-paste. Si el código descargado/copiado falla, no es culpa mía. Es la Providencia.
  • Si mi aplicación falla, el error está en el módulo que ha escrito otro programador.
  • Siempre uso la última versión de toda herramienta o framework. Sé que falla mucho, pero la penúltima ya no se lleva.
  • En un día lo termino todo tal y como estimé. Lo que hago durante los otros 30 días que dura el desarrollo son arreglos y ajustes sin importancia.
  • Si la solución a una necesidad muy concreta es trivial, siempre es preferible hacer un desarrollo complejo y genérico para posibles necesidades futuras.
  • Eso ya está hecho. Tengo un “to-do” en el código.
  • Si entrego tarde, no tiene nada que ver el tiempo que he estado en Facebook o chateando. Es que el proyecto estaba mal estimado.
  • Eso no se puede hacer.
  • Si hago la aplicación como me da la gana, es porque el lamentable documento de análisis me obliga a potenciar mi creatividad.
  • No es un bug, es una feature.

¿Falta alguna?

Vídeo de la ponencia en Decharlas

2 agosto 2010

Dicen que más vale tarde que nunca, así que aquí va el vídeo de mi ponencia en la primera edición de las Jornadas Symfony celebradas los pasados 5 y 6 de Julio en Castellón. He de decir que, a parte de disfrutar de un alto nivel en las charlas del resto de los ponentes, me divertí como un enano y tuve la oportunidad de conocer a un montón de gente realmente interesante. Un aplauso para la organización y en especial a David Castelló por el brillante trabajo.

Symfony en España. Caso práctico I: voota.es – decharlas 2010 from decharlas.com on Vimeo.

Y la presentación de la ponencia:

Cómo interactuar con tus técnicos

9 junio 2010

Últimamente estoy oyendo (más veces de lo habitual) lo difícil que es entenderse con esa gente que llaman “los informáticos” a distintas personas relacionadas con la creación de sitios web. La cosa es, cuando menos, preocupante. Me parece esencial tener una buena comunicación con tus técnicos para poder construir un buen portal web. Especialmente me refiero a la gente con la que más nos toca trabajar: Diseño, usabilidad y jefes de producto, …. Quisiera aclarar que, aunque trabajamos con máquinas, somos profundamente humanos y por lo tanto, sí, se puede hablar con nosotros.

Tank, I need an exit.....Fast!

Visto esto e inspirado por mi amiga Olga y su post de “Los otros” me he decidido a escribir unos consejillos de cómo tú (diseñador, responsable de usabilidad, jefe, CEO, …) podrías interactuar mejor conmigo (léase los informáticos).

  • Tip #1: No me hagas trabajar. Al menos para nada. Es mejor no reinventar la rueda (salvo que seas un fabricante de ruedas, claro). Déjame utilizar cosas estándar del mercado aunque no se ajusten al milímetro a lo que tienes en mente. Seguro que sirve igual y, además, nos evitamos un montón de trabajo de desarrollo, depuración de errores, … de trabajo del pesado.
  • Tip #2: El trac lo aguanta todo (TM). Utiliza algún sistema de gestión de tickets para crear tareas o reportar errores. Si no puede ser, utiliza el email. Si me dices al oído eso de “anda amigo, cuando tengas un hueco hazme el favor de …”, lo más probable es que ocurra una de estas dos cosas: Que se me olvide lo que me has pedido, o que haga como que se me ha olvidado. ¿Quieres echar un vistazo al Trac de Voota?
  • Tip #3: Mañana también existe. No me digas que todo es super-mega-crítico porque entonces nada lo será. Si tienes alguna idea importante o algo que no va como quisieras, casi siempre pude esperar a la siguiente release. No me hagas dejarlo todo para atender a tu capricho. Vale, sí, hay cosas que no pueden esperar a mañana …. Pocas.
  • Tip #4: No despliego los viernes ni después de las 12. Es verdad, lo confieso, me gusta la cerveza. Muchas tardes después del trabajo y, sobre todo, el fin de semana, me gusta tomarla. Lo prefiero a estar atendiendo incidencias provocadas por subir cosas a producción a última hora, deprisa y corriendo.
  • Tip #5: El que lo abre lo cierra. Si me abres una incidencia o me pides un desarrollo, no te olvides de cerrarlo. Revisa que efectivamente es lo que pedías y que todo está correcto. Esto evitará que, más adelante, tengamos errores en producción descontrolados.
  • Tip #6: Dame detalles, no la tabarra. Cuando informes de un error dame detalles precisos: Donde falla con que datos o en que url. Recuerda que a menudo un pantallazo vale más que 1.000 palabras. Con mucha prosa me mareo, me aburro y me invitas a procrastinar.
  • Tip #7: Ya voy. Si no esperas a que termine, es probable que no funcione. Revisar es bueno, pero espera a que el trabajo este hecho. Es bastante habitual ponerse a probar un desarrollo o incidencia antes de que te diga que está listo para revisar: Fail!
  • Tip #8: Trabajo para tí, aunque esto jamás te lo voy a decir. Es importante entender que si me facilitas el trabajo y me ayudas a trabajar mejor y más rápido, el que ganas eres tú, tu negocio o tu portal.

En fin amigos, espero que “los informáticos” vayamos perdiendo poco a poco esa fama de bichos raros y que la comunicación sea cada vez más fácil. Se que hablo desde mi técnico punto de vista, así que si tienes algo que decir, no te cortes 😉

Un workflow sencillo con git

4 junio 2010

Uno de los grandes quebraderos de cabeza del desarrollo web es el control del ciclo de vida. Cuando la cosa se pone seria, muchos desarrolladores, muchos cambios etcétera, se hace imprescindible alguna metodología compleja tipo integración continua. Sin embargo, en la mayoría de los casos es suficiente con tener un poco de orden y unos procedimientos claros.

Gráfico GitHub de los commits de Voota

Gráfico GitHub de los commits de Voota

Es, sin duda, el gestor de versiones el principal aliado para gestionar correctamente el ciclo de vida. Este es el workflow que utilizamos en Voota con git:

  1. Cada desarrollador “sube” sus cambios al repositorio de software cada vez que realiza un desarrollo. Para ello se utiliza la rama “master” en git, que es, por decirlo de alguna manera, la arteria principal del desarrollo. Es el proyecto vivo que se irá actualizando diariamente.
    git commit -am “Resuelto el ticket #nnn”
    git push
  2. Cuando hay un “change set” razonable, o lo que es lo mismo, ya se tienen unos cuantos cambios que queremos que sean revisados, se envían al servidor de pruebas (“stage”). En el servidor de pruebas hay una copia (“clone”) exacta del código fuente, pero que, para que funcione en modo test, se realizan algunos cambios básicos. En el caso de Voota se copian los scripts de php que ponen a Symfony en modo test (en realidad esto sólo se hace una vez al instalar el servidor):
    mv frontend_test.php a index.php
    mv backend_test.php a backend.php

    A continuación se utiliza la magia de git. Se actualizan los fuentes con rebase. La gracia de “rebase” es que re-aplica las acciones que se han realizado (como los mv de arriba) sobre la copia local después de actualizar los cambios desde el repositorio. De este modo no es necesario volver a hacer las modificaciones.

    git pull –rebase
  3. Para el paso a producción hace falta un poco más de control. Se debe implementar un mecanismo que permita al desarrollador retomar el código en el estado exacto que está en producción. Este es el uso que damos a las etiquetas (tags) de git:
    git tag milestone1_8_5
    git push –tags

    Esto creará una foto del proyecto en su estado actual, con todo el conjunto de fuentes agrupado bajo el nombre de etiqueta milestone1_8_5. Como curiosidad, se pueden ver aquí las etiquetas que tenemos en el git de Voota.
    El resto es similar al entorno de pruebas, con la diferencia que no se actualizarán los programas de la rama “master” como antes, si no que se hará de la etiqueta recién creada:

    git pull –rebase origin refs/tags/milestone1_8_5

Alguien que conozco diría “Todo perfecto. Invitar a cañas” 😉 … pero, ¿que pasa si se sigue desarrollando en la rama “master” y se detecta un error importante en producción?¿a alguien le ha pasado alguna vez? Nada, se arregla y listo. Ahí va el procedimiento:

# Por si algún otro desarrollador ya lo ha hecho antes, se actualizan las etiquetas desde el repositorio:
git fetch –tags

# Se crea una rama basada en la etiqueta de la versión en producción:
git checkout milestone1_8_5 -b b_milestone1_8_5

#####################################
# Se hacen cosas: Arreglar el bug por ejemplo 😉
#####################################

# Se suben los cambios a git:
git commit -am ‘se explica lo que se ha hecho un poco’

# Se actualiza la etiqueta:
git tag -f milestone1_8_5

# Se “empuja” al repositorio
git push –tags

# Volvemos a la rama principal en la copia local
git checkout master

# Se aplica el parche a la versión en desarrollo para que no se pierda en la siguiente release
git merge b_milestone1_8_5

# Se borra la rama creada para la ocasión
git branch -d b_milestone1_8_5

Ahora en el servidor de producción se actualiza la versión “tirando” de la etiqueta:

git pull –rebase origin refs/tags/milestone1_8_5

Trabajar con git tiene muchas ventajas y una de ellas es hacer las cosas fáciles y rápidas. Creo que este es un buen ejemplo.

github: Un nuevo hogar para el código fuente de Voota

8 marzo 2010

Siguiendo la política de transpariencia de Voota, esta semana hemos dado otro pasito. Nos hemos quitado de encima todo el código y le hemos buscado un sitio donde, pensamos, estará más cómodo.

Voota en github

Voota en github

Hasta ahora lo teníamos alojado en un servidor propio gestionado con subversion. Hoy Voota está en github, un servicio especializado en alojar software libre, donde cualquiera podrá acceder, comentar, reportar errores y muchos otro servicios. Además, pasamos de subversion a git que nos trae algunas funcionalidades nuevas.

¿Por qué este cambio?

Pensamos que es el lugar natural para un proyecto de estas características:

  • Porque el código fuente de Voota será más accesible, más fácilmente localizable para cualquiera que lo busque o lo quiera ver.
  • Porque estará más cerca de la comunidad de desarrolladores, gente que puede estar interesada y/o que puede aportar conocimiento.
  • Porque estará gestionado por expertos en el tema.
  • … y, además, quitará parte del trabajo de gestión a éste que suscribe. Eso siempre es bueno 😉

… y con el paso a git (vs. subversion):

  • Ganamos un entorno distribuido en el que no hace falta estar conectado con un servidor para utilizar el control de versiones.
  • Mejora sustancial de la gestión de ramas (branching).
  • Flexibilidad y eficiencia. Poco se puede decir de git que no esté dicho ya. Sólo puedo añadir que uno no es consciente de su potencia hasta que comienza a utilizarlo.

Dicho esto, estáis todos invitados a ver, descargar, comentar y cotillear por el código de Voota. Estará encantado de recibiros en su nueva casa 😉

Traducción web rápida y fácil con Symfony y Pootle

8 febrero 2010

El tema de las traducciones es, muchas veces un verdadero dolor de cabeza. La creación del código multi-idioma, la extracción de etiquetas y el envío y recepción de los textos al traductor son tareas que se pueden simplificar notablemente utilizando las herramientas apropiadas. Ahí va nuestra propuesta:

  • Codificación de las vistas (páginas) con etiquetas traducibles. El ejemplo a continuación es un extracto de una vista de Symfony :

    […]

    <li><h2><?php echo __(‘Comparte opiniones sobre políticos de España.’) ?></h2></li>

    […]

    Codificar las vistas de esta forma permite ver el html casi como será generado en el idioma original pero dando la posibilidad de traducir todos los literales que se encuentren entre ‘__(‘ y ‘)’.

  • Extracción de etiquetas. Un simple comando permite extraer todas las etiquetas a un fichero XLIFF:
    php symfony i18n:extract –auto-save frontend ca

    Este comando generará un fichero para almacenar las traducciones al catalán (‘ca’) de cada etiqueta encontrada en todas y cada una de las vistas de la aplicación (‘frontend’). Algo así como ‘…/ca/messages.xml’.
    Lo ideal es almacenar este fichero en un repositorio de software junto con el resto del código del proyecto. En nuestro caso utilizamos un servidor svn.

  • La magia de Pootle. La aplicación de Pootle deberá estar instalada en un servidor con acceso al repositorio svn. Habrá que configurar permisos y accesos para cada traductor. Una vez esté listo, Pootle permite conectarse con svn para obtener el fichero de etiquetas generado por Symfony. El traductor podrá conectarse vía web a la aplicación para ver y traducir todas aquellas que pertenezcan a sus proyectos y lenguajes asignados.
    Interfaz de traducciones - Pootle

    Interfaz de traducciones - Pootle

    Desde el propio interfaz de Pootle, siempre con los permisos apropiados, se puede enviar de nuevo el fichero con las traducciones realizadas de nuevo al repositorio de software. Sobra decir que, además, Pootle ofrece un montón de utilidades más sobre las traducciones, como estadísticas, traducciones dudosas o poco claras, perfiles para sugerir y otros para confirmar, etc..
    Te invitamos a que eches un vistazo al Pootle de Voota: http://pootle.voota.org/

Nunca fue tan fácil tener sitios en varios idiomas. Ahora solo necesitamos los traductores que, por el momento, seguirán siendo humanos 😉

SfReviewPlugin 1.0: Nueva versión del plugin de opiniones para Symfony

18 enero 2010

Hoy ya hemos puesto a disposición de todos la versión 1.0 de SfReviewPlugin. Se trata del plugin de symfony que desarrollamos y utilizamos en Voota para la gestión de opiniones sobre políticos (y muy pronto sobre partidos).

Aunque sigue siendo una versión beta, hemos decidido etiquetarla 1.0 para seguir con la numeración de los milestones de voota.

Descarga

Puedes obtener la versión instalable directamente del sitio de symfony:

http://www.symfony-project.org/plugins/sfReviewPlugin

Para obtener los últimos cambios día a día, puedes bajarte los fuentes del repositorio svn de Voota:

http://trac.voota.org/browser/trunk/www/plugins/sfReviewPlugin

Novedades

  • La novedad principal, sin duda, es la posibilidad de opinar/votar sobre otras opiniones.

    Opinando sobre un comentario

    Opinando sobre un comentario

  • Opiniones “culturizadas”. Hemos introducido el idioma del usuario a la opinión para, de esta forma, poder distinguir el idioma en la página donde aparecen los comentarios.
  • Paginación “tipo twitter”. Para mejorar la experiencia de usuario hemos introducido un botoncito que dice “más” cuando no caben todos los comentarios. Al pulsarlo aparecerá otra página de comentarios “inline” por ajax (sin necesidad de recargar la página). Ej.: Página de Zapatero en Voota
  • Mejoras en el sistema de moderación: Más filtros, más facilidad para encontrar comentarios y mejor interfaz para visualizar el comentario con enlace a la “entidad comentada”.

    Moderación de comentarios

    Moderación de comentarios

  • Y, como siempre, un montón de pequeñas mejoras y correcciones que hacen la vida un poco más fácil 😉

En definitiva, seguimos trabajando en el sistema de opiniones como uno de los módulos principales de Voota. Ójala te sea útil a tí también y compartas con nosotros tus impresiones.

Mejorando el rendimiento de Symfony a base de caché

17 diciembre 2009

Symfony no es lento

Se dice que utilizar un framework en general y Symfony en particular penaliza el rendimiento de una aplicación web. Es cierto, al menos a priori. Por mucho trabajo de optimización que se haga, las propias clases del framework consumirán tiempo y recursos y tampoco serán las óptimas las queries de acceso a base de datos generadas. Siempre será más eficiente un código personalizado para la ocasión que un código genérico.

Dicho así podría parecer que es preferible invertir tiempo en hacer código a medida que utilizar herramientas como Symfony. Nada más lejos de la realidad. Una de las cosas que proporciona Symfony, y que compensa con creces “su lentitud”, es un sistema de caché que con muy poco esfuerzo permitirá a una aplicación desarrollada en Symfony “correr” mucho más rápido que una aplicación hecha “a mano”. ¡Ojo! Esto no quita la responsabilidad de hacer un código eficiente.

Activando la caché de página

Efectivamente, hay muchas formas de optimizar el rendimiento de una aplicación, pero sin duda, la caché de página es la que marca la diferencia. Para activarla en Symfony solo hay que crear el fichero cache.yml en el directorio config del módulo (ej. apps/frontend/modules/politico/config/) activando la cache para cada acción en la que se quiera poner en caché:

ranking:
 enabled: on
 with_layout: false
 lifetime: 60

show:
 enabled: on
 with_layout: false
 lifetime: 360

“ranking” y “show” son dos de las acciones del módulo. “with_layou: false” indica que sólo ha de guardarse el código específico de esta vista, no el de layout.php. “lifetime” es el tiempo en segundos que tardará en limpiarse la caché automáticamente.

Limpiando la caché manualmente

Symfony proporciona información del estado de la caché si se necesita

Una de las opciones para limpiar la caché de una página es esperar a que pase el tiempo indicado en “lifetime” en el fichero de configuración. Como esto muchas veces no es una opción, Symfony proporciona un mecanismo para limpiarla por código. El siguiente snipplet (pedacito de código) muestra como, en Voota, se limpia la caché de la página de un político cada vez que alguien deja un comentario:

$cacheManager = $this->getContext()->getViewCacheManager();
if ($cacheManager != null) {
$cacheManager->remove(“politico/show?id=”.$politico->getVanity().”&sf_culture=es”);
$cacheManager->remove(“politico/show?id=”.$politico->getVanity().”&sf_culture=ca”);
}

La clase sfViewCacheManager permite interactuar con el sistema de caché de Symfony. El método “remove” limpia la página que se quiera.

Más rápido incluso

Otra de las funcionalidades que ofrece Symfony es delegar la gestión de la caché a un sistema externo. Unos de los sistemas más conocidos y utilizados dentro y fuera de Symfony es memcached. Una buena idea será dejarle la gestión a él. Esto se configura en el fichero de factorías de la aplicación (apps/frontend/config/factories.yml):

dev:
 view_cache:
  class: sfMemcacheCache
   param:
    lifetime:                  86400 #24h
    prefix:                    vo
    servers:
     server_01:
      host: localhost
      post: 11211

El resto exactamente igual. No será necesario tocar ni una línea de código para esto.

sfReviewPlugin: Plugin symfony para dejar opiniones sobre “cualquier cosa”

30 noviembre 2009

Como parte del desarrollo de Voota estamos creando un plugin genérico para dejar opiniones: sfReviewPlugin. En su primera versión, Voota permite opinar sobre políticos, pero pronto permitirá opinar sobre partidos políticos y, más adelante, sobre otras “entidades”.

Como se puede ver en el decálogo  de Voota, parte de nuestro compromiso es con el software libre y, por lo tanto, pretendemos ir a aportando cualquier pieza de software que vayamos produciendo. Hoy tenemos ya publicada la primera versión del sistema de opiniones:

¿Qué es sfReviewPlugin?

Editando una opinión con sfReviewPlugin

Es un plugin genérico para valorar y opinar sobre cualquier elemento de un sitio web desarrollado con Symfony. Está basado en sfGuardPlugin como gestor de usuarios y en JQuery (sfJqueryReloadedPlugin) como api javascript/ajax.

Donde bajarlo y cómo instalarlo

El plugin está alojado en el propio sitio de symfony:

http://www.symfony-project.org/plugins/sfReviewPlugin

En la pestaña “Readme” se pueden encontrar las instrucciones para descargarlo, instalarlo y realizar una configuración básica.

Los fuentes están disponibles en el repositorio de software de Voota:

http://trac.voota.org/browser/trunk/www/plugins/sfReviewPlugin

Cualquier duda / problema / sugerencia será muy bien recibida en este blog, en mi twitter o en la dirección de email de temas técnicos de Voota: tech [arr0ba] voota.es

Suma y sigue

Como todas las primeras versiones esto no es más que una beta del plugin. Para el siguiente milestone de Voota ya estamos trabajando en las opiniones sobre opiniones (para permitir el debate entre usuarios) y, muy pronto, este mismo plugin permitirá cargar imágenes y vídeos con el comentario.

Como implementar Sphinx con symfony

23 noviembre 2009

Como primera aproximación a un buscador simple en la primera versión de Voota, se nos ocurrió utilizar “Google custom search“. Mala idea. Hoy, 5 días después de la puesta online, Google solo ha indexado 267 páginas y teniendo en cuenta que empezábamos con 1.549 políticos con sus 1.549 correspondientes fichas, los resultados no eran muy apropiados. Por ejemplo, buscando “Zapatero” aparecían varios resultados del blog, alguna ficha de otros políticos y varios enlaces al ranking, pero no la ficha del sr. presidente.

Necesitábamos un buscador, sencillo, potente y que escalase bien con los futuros desarrollos que vienen. La solución fue mucho más fácil de lo esperado. Decidimos implementar nuestro propio motor de búsqueda con Sphinx. Así es como lo hicimos:

  1. Lo primero es instalar el motor de búsqueda, que básicamente consta de dos partes: El indexador, que obtiene las palabras clave de la base de datos (Postgresql o mysql) y el demonio o servicio de búsqueda que atiende a las peticiones del servidor web.
    La instalación no tiene más misterio que seguir los pasos que explican en su web: Manual de referencia de Sphinx.
  2. Después viene la fase de configuración. Aquí es donde se le dice a Sphinx que datos tiene que indexar para que puedan ser encontrados en el buscador del sitio web. En nuestro caso, de momento, sólo queríamos indexar los políticos:
    source src1
    {
    type                                    = mysql
    sql_host                                = localhost
    sql_user                                = usuario
    sql_pass                                =
    sql_db                                  = voota
    sql_port                                = 3306  # optional, default is 3306
    sql_query_pre   = SET NAMES utf8
    sql_query                               = \
    SELECT id, vanity, alias, nombre, apellidos, bio, presentacion, residencia, formacion \
    FROM politico
    sql_ranged_throttle     = 0
    sql_query_info          = SELECT * FROM politico WHERE id=$id
    }
    source src1throttled : src1
    {
    sql_ranged_throttle                     = 100
    }
    index politico
    {
    source                  = src1
    path                    = /var/data/voota
    docinfo                 = extern
    mlock                   = 0
    morphology              = none
    min_word_len            = 1
    charset_type            = utf-8
    charset_table   = 0..9, A..Z->a..z, a..z, \
    U+C0->a, U+C1->a, U+C2->a, U+C3->a, \
    U+C4->a, U+C5->a, U+C6->a, \
    U+C7->c,U+E7->c, U+C8->e, U+C9->e, \
    U+CA->e, U+CB->e, U+CC->i, \
    U+CD->i, U+CE->i, U+CF->i, U+D0->d, \
    U+D1->n, U+D2->o, U+D3->o, \
    U+D4->o, U+D5->o, U+D6->o, U+D8->o, \
    U+D9->u, U+DA->u, U+DB->u, \
    U+DC->u, U+DD->y, U+DE->t, U+DF->s, \
    U+E0->a, U+E1->a, U+E2->a, U+E3->a, \
    U+E4->a, U+E5->a, U+E6->a, \
    U+E7->c,U+E7->c, U+E8->e, \
    U+E9->e, U+EA->e, U+EB->e, U+EC->i, \
    U+ED->i, U+EE->i, U+EF->i, \
    U+F0->d, U+F1->n, U+F2->o, U+F3->o, \
    U+F4->o, U+F5->o, U+F6->o, \
    U+F8->o, U+F9->u, U+FA->u, U+FB->u, \
    U+FC->u, U+FD->y, U+FE->t, U+FF->s,
    html_strip                              = 0
    }

    Extracto del fichero de configuración de Sphinx

  3. A continuación se arranca el servicio de búsqueda:
    sudo searchd –config /usr/local/etc/sphinx.conf
    y se da la orden para que Sphinx realice la indexación (Esto será necesario hacerlo periódicamente):
    sudo /usr/local/bin/indexer politico –rotate
    Muy bien, Sphinx configurado y escuchando.
  4. Sólo falta escribir el código Symfony para interrogar al motor de búsqueda:
    $this->q = $request->getParameter(“q”);$cl = new SphinxClient ();
    $cl->SetServer ( ‘localhost’, 3312 );
    $this->limit = 1000;
    $cl->SetLimits ( 0, $this->limit, $this->limit );
    $cl->SetArrayResult ( true );
    $this->res = $cl->Query ( SfVoUtil::stripAccents( $this->q ), ‘politico’ );
    if ( $this->res!==false ) {
    if ( isset($this->res[“matches”]) && is_array($this->res[“matches”]) ) {
    $c = new Criteria();
    $list = array();
    foreach ($this->res[“matches”] as $idx => $match) {
    $list[] = $match[‘id’];
    }
    $c->add(PoliticoPeer::ID, $list, Criteria::IN);
    $c->addDescendingOrderByColumn(PoliticoPeer::SUMU);
    $this->politicosPager = new sfPropelPager(‘Politico’, 10);
    $this->politicosPager->setCriteria($c);
    $this->politicosPager->setPage($this->getRequestParameter(‘page’, 1));
    $this->politicosPager->init();if ($this->politicosPager->getNbResults() == 1){
    $res = $this->politicosPager->getResults();
    $this->redirect( “@politico_”.$this->getUser()->getCulture( ‘es’ ).”?id=”.$res[0]->getVanity() );
    }
    }
    }

    Código Symfony que realiza la búsqueda

Listo, hoy puedes buscar Zapatero, José Luis Rodriguez o ZP en Voota, que seguro que encuentras lo que buscas, a no ser que quieras comprarte unos zapatos nuevos, claro 😉