Conector Symfony2 Simple Machines Forum

Introducción

El objetivo de este tutorial es describir una solución para sincronizar la autenticación de symfony2 (sf2) con los foros de Simple Machines Forums (SMF). A día de hoy no hay ningún bundle de foros para symfony listo para producción. CCDNForumForumBundle es lo mejor que he encontrado pero lamentable su desarrollador no lo mantiene ya. SMF ofrece una serie de ventajas que lo convierte en una solución atractiva:
  • Comunidad activa
  • Actualizaciones frecuentes y fáciles de aplicar
  • Modulable
  • Customizable
  • Gratis y de código libre (licencia BSD)
  • Soporta más de 40 idiomas
  • Interfaz atractiva e intuitiva
  • Gran variedad de funcionalidades para usuarios, moderadores y administradores
Pero no todo son ventajas. Su código está un tanto desorganizado y utiliza una base de datos sin integridad referencial. Aun así, sus desarrolladores se han preocupado por ofrecer soluciones programáticas para integrar y extender sus funcionalidades sin tener que modificar directamente los ficheros. Lo cual se agradece.
Te puede interesar este tutorial si… Utilizas sf2 con el bundle FOSUserBundle para gestionar tu base de usuarios y, además, tu organización requiere de un foro para éstos.
No te va interesar este tutorial si… Pretendes gestionar los usuarios desde SMF. Mi solución deshabilita la posibilidad de registrar usuarios desde el foro, o que éstos puedan modificar sus datos personales. Los datos han de ser actualizados desde sf2 y, a continuación, propagados programáticamente a SMF.
No entra en este tutorial la instalación y configuración de symfony y fosuserbundle. Se da por hecho de que existe una aplicación basada en sf2 con su tabla de usuarios. Tampoco se explicará la configuración de apache, php o mysql. O la instalación de módulos o paquetes de idiomas en SMF. De ahí que utilizaremos los nombres en inglés del apartado de administración de SMF.

Prerequisitos

Para llevar a cabo esta solución se han utilizado los siguientes componentes:
  • PHP, 5.6.9
  • MySql, 5.5.41
  • Apache, 2.4
  • Symfony, 2.5.12
  • FOSUserBundle, 1.3.6
  • SMF, 2.0.10
  • El paquete curl-easy, 1.1.4
Probablemente funcione con versiones menores, pero no lo he probado. Además, habremos configurado dos virtual hosts en apache, donde hospedaremos la aplicación de symfony y la de los foros:
  • Sf2: acme.com
  • SMF: foros.acme.com

Instalación, configuración y adaptación de SMF

Si tienes instalado y funcionando symfony2, doy por hecho que el despliegue de SMF es pan comido. Basta con descargarlo de la web oficial, descomprimirlo y desplegarlo donde apunte su correspondiente virtual host. En la dirección http://foros.acme.com/install.php, nos indicaran los pasos a seguir para su configuración incial. Una vez instalado, nos autenticamos con las credenciales del usuario administrador para aplicar los siguientes cambios de configuración:
  • Deshabilitar el registro de nuevos usuarios en SMF: Admin » Features and options » Members » Registration » Settings » Method of registration employed for new members: Registration disabled
  • Deshabilitamos el quick login: Admin » Features and Options » Layout » Show a quick login on every page
  • Habilitamos la posibilidad de compartir cookies entres subdominos: Admin » Features and Options » Configuration » Server Settings » Cookies and Sessions » Use subdomain independent cookies
  • Deshabilitamos la posibilidad de editar el perfil en SMF: Admin » Features and Options » Members » Regular Members » Mofify » Permissions » General Permissions » Personalize their profiles » Edit their account settings

Hooks para SMF

SMF ofrece a los desarrolladores la posibilidad de extender el comportamiento de los foros para integrarlos con aplicaciones externas. Gracias a una serie de anzuelos (hook en inglés) podemos enganchar bloques de código externo e interferir en acciones como la autenticación. O modificar el comportamiento de algunos de los botones. La lista de hooks disponibles es extensa, pero para nuestra solución sólo necesitaremos cuatro.
  1. integrate_pre_include con el que definiremos la ubicación del archivo con nuestros métodos adicionales.
  2. integrate_actions con el que modificamos algunas de las acciones de los foros.
  3. integrate_verify_user con el que verificaremos el usuario actual
  4. integrate_menu_buttons con el que podremos modificar el comportamiento de los botones del menú
Para dar de alta nuestras acciones personalizadas, crearemos el fichero add_action_hooks en la raíz de la aplicación de los foros, al mismo nivel que index.php E invocamos desde http://foros.acme.com/add_action_hooks.php. A continuación lo borramos, ya no lo vamos a necesitar. Lo que sí que vamos a necesitar es el fichero con los métodos enganchados, aquél que definimos con la clave integrate_pre_include:
Para que el invento funcione es importante que el nombre de la cookie de SMF sea el que viene por defecto, SMFCookie956. Se puede comprobar en /Settings.php
Bueno, ya tenemos listos los foros. Siguiente paso.

Adaptaciones en Symfony2

Configuración

Lo primero, tenemos que configurar las cookies de symfony. Esto es importante para identificar correctamente la cookie de cada aplicación. Es necesario que ambas aplicaciones puedan reconocerse a través de sus cookies, a pesar de estar en subdominios diferentes. Por supuesto, ambas aplicaciones han de compartir mismo dominio. Oh, y vamos a necesitar una serie de parámetros configurables, cuestión de no meterlos a pelo en el código.

Lógica

SMF ha de saber si el usuario está identificado en symfony. Claro está. Rápido, necesitamos un controlador y una ruta. Si no lo tenéis ya hecho, hay que dar de alta un par handlers que se encargarán de gestionar el flujo de la aplicación después de un login o logout. O sea, desconectar al usuario de los foros cuando éste se desconecte de ACME. Y redirigirle de vuelta a los foros después de una autenticación exitosa. Nótese la utilización del paquete cURL. Para incluirlo (curl-easy) hay que darlo de alta en composer.json y adaptar la clave «autoload» para que se pueda acceder por namespace Y, con esto, ya tenemos conectados symfony y SMF. Ya sólo nos queda «sincronizar» los datos. Cuando un usuario es dado de alto en smf2, hay que darlo de alta en SMF. O, si no, poco vamos a conectar… Y, por supuesto, debemos actualizar sus datos personales del foro (sobre todo el email) cuando se actualicen en ACME.

Replicación de datos Symfony -> SMF

Hay varias maneras de hacerlo. Una de ella es con triggers en la base de datos. A modo de ejemplo: AFTER UPDATE ON fos_user_user FOR EACH ROW BEGIN IF NEW.email <> OLD.email AND new.enabled = 1 THEN IF (SELECT COUNT(*) FROM smf.smf_members WHERE email_address = new.email) = 0 THEN INSERT INTO smf.smf_members SET email_address = NEW.email, is_activated = 1, date_registered = CURDATE(), real_name = NEW.firstname; ELSE UPDATE smf.smf_members SET smf.smf_members.email_address = NEW.email WHERE smf.smf_members.email_address = NEW.socio_id; END IF; END IF; IF NEW.enabled <> OLD.enabled THEN UPDATE smf.smf_members, acme.fos_user_user SET smf.smf_members.disabled = CASE WHEN NEW.enabled = 1 THEN 0 ELSE 1 END WHERE smf.smf_membersr.email_address = NEW.email; END IF; END$$ DELIMITER ; [/crayon] ¿Que lo queremos gestionar desde el propio symfony? Entonces tendríamos que engancharnos a algún EventListener. Por ejemplo, si utilizais SonataAdminBundle, en la clase de admin del usuario: Listos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *