Personalizar la consulta de ParamConverter

ParamConverter es una anotación que se usa en los controladores para preprocesar parámetros que llegan por la URL y convertirlos a objetos, FrameworkExtraBundle tiene por defecto Doctrine  y DateTime Converter, además se puede crear un converter fácilmente implementando una interfaz que proporcionan. En este artículo vamos a ver cómo extender Doctrine Converter para personalizar la consulta en Symfony2.1, ya que en la versión 2.2 vendrá por defecto.

Para ver un ejemplo vamos a suponer que tenemos una Entity User y que el username es un campo único, de normal para ver los detalles de un usuario haríamos algo así:

Esto mismo usando ParamConverter quedaría de la siguiente forma:

Incluso se puede omitir la anotación y dejar que por type hinting sepa sobre qué repositorio tiene que hacer la consulta. A mí particularmente no me gusta omitir la anotación, para que se sepa de dónde viene el objeto.

Ahora lo que vamos a hacer es muy sencillo y como comentábamos, ya vendrá por defecto en la versión 2.2, pero hasta entonces puede que nos sea de utilidad. Creamos una clase que sea DoctrineParamConverter que extenderá de la proporcionada por el Bundle:

Lo único que hace es sobrescribir los métodos find y findOne y el código es copiado de la versión 2.2. Ahora lo que haremos será redeclarar el parámetro que define cuál será la clase que implementa el Doctrine Converter e indicamos nuestra clase. Creamos un fichero llamado converters.xml bajo Resources/config:

Le indicamos a Symfony2 que cargue el nuevo fichero que hemos creado en AppSMTCExtension.php dentro del directorio DependencyInjection:

Y ya tendremos la posibilidad de indicar a qué metodo del repositorio va a llamar cuando llegue la petición.

Siguiendo con el ejemplo vamos a suponer que la Entity tiene un campo active y que sólo podemos ver los usuarios que son activos, entonces lo que haremos será indicar en el ParamConverter qué metodo del repositorio vamos a llamar:

Y en el repositorio:

Ahora si se hace una petición con un username de un usuario que no está activo no entrará a la acción del controller y lanzará un NotFoundHttpException.