Pasar al contenido principal

Entendiendo el registro de clases en Drupal: Caso con el módulo Bean

Hace unos días tuve un inconveniente particular, el módulo Bean que permite crear Bloques como entidades configurables dejó de funcionar y ya no me permitía gestionar los Tipo de Bloque, lo único que me mostraba era un error donde indicaba que el elemento que se estaba intentando cargar no era un objeto.

Después de varias horas haciendo un recorrido por el código de Bean, llegué al punto donde el módulo hacia la carga de los plugins y posteriormente se hacía una verificación para asegurar que la Clase ‘BeanPlugin’ existiera, esto lo hace en la función ctools_plugin_get_class, todo iba en orden, el plugin tenía la definición completa y bien estructurada, pero al final se hacía una última validación con la función de PHP class_exists, y en este punto el valor retornado era NULL, es decir, la clase no estaba registrada.

Lo primero que se me ocurrió fue realizar una limpieza de registro usando Registry Rebuild mediante Drush.

$ drush dl registry_rebuild

$ drush rr

Luego de realizar la limpieza pude comprobar que tampoco tenía efecto lo cual solo me dejaba como alternativa revisar el Core de Drupal para entender en que momento registraba las clases y porque “BeanPlugin” específicamente no estaba disponible.

Drupal al momento de instalar un módulo también identifica sus archivos y realiza un registro de clases asociadas, este registro lo mantiene en la tabla “registry”, al buscar en esa tabla noté que la clase “BeanPlugin” no se encontraba ahí, lo cual me indicaba que el archivo que la contenía no había sido parseado, esto me daba dos posibilidades, que PHP no haya identificado el archivo en la carpeta o que por algún motivo se haya perdido el registro de la clase luego de haberlo parseado en una anterior ocasión.

Lo primero que hice fue verificar que el archivo se encontrara en el registro, para ello verifiqué la tabla “registry_files”, los registros mostraban la ruta del archivo lo cual descartaba la primera posibilidad y solo era posible que se hubiese perdido el registro de la clase en la tabla “registry” por alguna razón, la solución debía ser que Drupal de nuevo hiciera el parseo y verificar que en esa ocasión si se registrara la clase.

La tarea no iba a ser sencilla pero tenía que empezar así que me basé en el script de Registry Rebuild para encontrar el punto de registro de las clases y también entender porque no me funcionó con Drush, la parte que me interesaba iniciaba con la ejecución de la función registry_rebuild, la cual llama a registry_update que a su vez ejecuta a _registry_update, esta última función hace la labor de identificar los directorios de los módulos y parsear los archivos .info para identificar la información y archivos asociados, si revisamos el archivo .info del módulo Bean nos encontramos con la siguiente línea:

files[] = plugins/BeanPlugin.class.php

Lo anterior le está indicando que ese archivo es necesario por el módulo y por ende es candidato para ser parseado.

Continuando con la exploración encontramos dentro de _registry_update una función que hace la tarea de parsear los archivos identificados, estoy hablando de _registry_parse_files la cual determina si un archivo debe ser parseado o no basándose en el hash, aquí fue cuando entendí lo que sucedía. Había un condicional que decía que si el archivo ya estaba registrado y el valor del hash no había variado, es decir, el archivo no tenía modificaciones no era necesario volver a parsearlo, esa condición tenía mucho sentido, en caso de habilitar un nuevo módulo Drupal no tendría que volver a recorrer absolutamente todos los archivos a no ser que fuese necesario, sin embargo esa medida me estaba afectando porque el archivo no había sido modificado y también estaba registrado en la tabla “registry_file” por lo tanto lo saltaba, ahora entendía la razón del por qué con $ drush rr no funcionó.

Entendido el problema la solución debía ser más sencilla, solo debía remover el registro del archivo de la tabla “registry_file” y eso ya era un motivo para que se volviera a parsear, para asegurarme borré el registro de todos los archivos relacionados al módulo en la tabla “registry_file” y volví a a ejecutar

$ drush rr

Una vez terminado volví a verificar la tabla registry y en esta ocasión si estaba la clase que necesitaba, posteriormente volví a probar el módulo y ¡todo funcionaba perfectamente!.

Esta no era la primera vez que me sucedía este caso con el módulo Bean, la anterior ocasión resolví desinstalar el módulo por que no tenía muchos datos, pero en este caso no podía hacer lo mismo, no estoy seguro de si es un problema con el módulo o alguna acción administrativa sin intención que lo provoca, solo se que me forzó a ir al fondo del problema y entender mejor el sistema de registro.

Espero que la explicación de esta solución aporte a entender como funciona el registro de archivos y clases en Drupal para que tengan alternativas en casos similares.

Añadir nuevo comentario