Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Drupal

Uso y ampliación de la API de Drupal 8 Mail: Parte 2

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Using and Extending the Drupal 8 Mail API.
Using and Extending the Drupal 8 Mail API: Part 1

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

En el artículo anterior vimos cómo podemos enviar mensajes de correo electrónico programaticamente en Drupal 8. También vimos cómo otros módulos pueden alterar estos mensajes de correo salientes. Hoy, vamos a ver cómo podemos usar la API de correo para extender este comportamiento predeterminado. El propósito es utilizar un servicio externo como un medio para la entrega de correo electrónico.

Para ello, vamos a utilizar Mandrill, aunque el enfoque del artículo no será su API o cómo trabajar con él, sino más bien el lado Drupal de las cosas. Y recuerde, el módulo de trabajo se puede encontrar en este repositorio en Git.

Como hemos visto en el artículo anterior, el envío de un correo electrónico en Drupal 8 ocurre solicitando el administrador de correo, pasando algunos parámetros a su método mail() y configurar una plantilla dentro de una implementación hook_mail(). Lo que el administrador de correo hace internamente es cargar el complemento de correo adecuado, crear el correo electrónico y, a continuación, delegar al método mail() cualquier plugin que se cargó.

Pero, ¿a quién se delega realmente?

Selección de complemento

Una cosa importante a entender antes de escribir nuestro propio complemento es el proceso de selección del administrador de correo para cargar complementos. En otras palabras, ¿cómo sabemos qué complemento se cargará y cómo podemos hacer que cargue el nuestro?

La array de configuración system.mail.interface contiene todas las respuestas. Contiene los identificadores de los complementos disponibles, marcados por el contexto en el que se usan. Por defecto, todo lo que tenemos dentro de esta configuración es default => phpmail. Esto significa que el complemento con id phpmail (la clase PHPMail) se utiliza como respaldo para todos los contextos que no se especifican de otro modo, es decir, el valor predeterminado.

Si queremos escribir nuestro propio complemento, necesitamos agregar otro elemento en esa matriz con el ID de complemento como su valor. La clave para este valor puede ser una de dos cosas: el nombre de la máquina de nuestro módulo (para cargar el plugin siempre que nuestro módulo envíe mensajes de correo electrónico) o una combinación de nombre de módulo y plantilla de correo electrónico clave (para cargar el plugin siempre que nuestro módulo envía un correo electrónico Utilizando esa clave específica).

Un ejemplo de la última construcción es d8mail_node_insert, donde d8mail es nuestro nombre de módulo que empezamos a construir en el artículo anterior, y node_insert es la clave de plantilla de correo electrónico que definimos.

Así que ahora que sabemos cómo ocurre la selección de complementos de correo, debemos asegurarnos de que esta matriz de configuración contenga la información necesaria para que los correos enviados con nuestro módulo d8mail usen el nuevo complemento que vamos a construir. Podemos hacer esto dentro de una implementación hook_install() que se dispara sólo una vez cuando el módulo se instala:

d8mail.install:

No es complicado lo que pasa arriba. Cargamos el objeto de configuración editable que representa la configuración de system.mail y añadimos un nuevo elemento a la array interface: d8mail => mandrill_mail. Pronto crearemos un plugin de correo con el id de mandrill_mail que se utilizará para todos los correos electrónicos enviados por el módulo d8mail. Y eso es todo.

Pero antes de avanzar, necesitamos asegurarnos de que este cambio se revertirá cuando el módulo se desinstale. Para ello, podemos utilizar la contrapartida hook_uninstall() que se llama cuando un módulo se desinstala (no hay más módulo de desactivación en Drupal 8).

Dentro del mismo archivo:

Con la implementación hook_uninstall() hacemos lo contrario de antes: eliminamos nuestro id de complemento si está configurado.

El escenario de instalación / desinstalación es solo un camino a seguir. También puede crear un formulario de administración que permita a los usuarios seleccionar el complemento que desee y en qué contexto. Pero todavía debe asegurarse de que al deshabilitar el módulo que define un complemento en particular, la configuración ya no guardará una referencia a ese complemento. De lo contrario, el administrador de correo puede tratar de utilizar una clase inexistente y lanzar todo tipo de errores.

Mandrill

Como mencioné antes, trabajaremos con la API Mandrill para ilustrar nuestra tarea. Así que vamos a cargar la Biblioteca PHP de Mandrill y hacerla disponible en nuestro entorno. Hay tres pasos que tenemos que hacer para esto.

Primero, necesitamos conseguir la biblioteca dentro de Drupal. En el momento de la escritura, esto significa básicamente la adición de la "mandrill/mandrill": "1.0.*" Dependencia para el archivo composer.json raíz y ejecutar composer install. Tenga en cuenta, sin embargo, que esto también borrará la instalación de Drupal desde dentro de la carpeta core/ y descargará la última versión estable en su lugar. A continuación, tendrá que editar el archivo raíz index.php y cambiar la ruta al autoloader según estas instrucciones. Esperemos que esta última acción no sea necesaria en el futuro, y le animo a seguir las discusiones sobre el futuro de Composer en Drupal 8 para administrar bibliotecas externas.

En segundo lugar, necesitamos obtener una clave API de Mandrill. Afortunadamente, esto se puede generar fácilmente desde sus páginas de administración. Una vez que lo tengamos, podemos almacenarlo dentro de un nuevo archivo creado en nuestro servidor, en cualquiera de las ubicaciones:

También podemos pasar la clave como un parámetro de constructor a la clase Mandrill principal, pero de esta manera no tendremos que codificarla en nuestro código.

En tercer lugar, tenemos que crear un servicio para que podamos utilizar la inyección de dependencia para pasar la clase Mandrill en nuestro complemento:

d8mail.services.yml:

Dependiendo de cómo haya cargado la clase Mandrill en su aplicación, deberá cambiar el valor después de class. Utilizando el método composer.json, esto será suficiente.

El complemento Mail

Finalmente es el momento de crear nuestro complemento. En Drupal 8, las clases de plugin van dentro de la carpeta src/Plugin de nuestro módulo. Dependiendo de su tipo, sin embargo, se colocan más abajo dentro de otros directorios (en nuestro caso Mail). Vamos a escribir nuestra clase que dependerá de la biblioteca Mandrill API para enviar correos electrónicos:

src/Plugin/Mail/MandrillMail.php:

Hay un par de cosas a tener en cuenta antes de entrar en lo que hace la clase.

En primer lugar, las anotaciones por encima de la clase. Este es sólo el mecanismo de descubrimiento de complementos más común para Drupal 8. La clave id coincide con el valor que añadimos anteriormente a la matriz de configuración system.mail.interface, mientras que el resto son elementos básicos de definición de complemento.

En segundo lugar, la implementación de la interfaz ContainerFactoryPluginInterface mediante la cual definimos el método create(). Este último es parte del proceso de inyección de dependencias mediante el cual podemos cargar el servicio Mandrill que definimos anteriormente en el archivo services.yml. Esto hace que la prueba sea mucho más fácil y se considere la mejor práctica.

Como ya he mencionado, los complementos de correo necesitan implementar la interfaz MailInterface que impone la existencia de los métodos format() y mail(). En nuestro caso, el primero hace exactamente lo mismo que el plugin PHPMail: un poco de procesamiento del cuerpo del mensaje. Así que puede agregar su propia lógica aquí si lo desea. El segundo método, por otra parte, es responsable de enviar el correo hacia fuera, en nuestro caso, usando la propia API Mandrill.

Como instruye la documentación de Mandrill, construimos un mensaje de correo electrónico dentro de la matriz $vars usando valores pasados del administrador de correo a través del parámetro $message. Estos ya se filtrarán a través de hook_mail(), hook_mail_alter() y el propio format() del plugin. Todo lo que queda es enviar el correo electrónico. No entraré en los detalles del uso de la API Mandrill, ya que puede consultar la documentación de todas las opciones que puede utilizar.

Después de enviar el correo electrónico y volver de Mandrill un estado sent, devolvemos toda la matriz de respuestas, que contiene más información. Esta matriz luego se agrega por el administrador de correo a su propia array devuelta con una clave result. Si Mandrill tiene un problema, rechaza el correo electrónico o lanza una excepción, devuelve false. Esto hará que el administrador de correo maneje esta situación registrando el incidente e imprimiendo un mensaje de estado.

Y eso es más o menos. Podemos borrar la caché e intentar crear otro nodo de artículo. Esta vez, el correo electrónico de notificación debe ser enviado por Mandrill en lugar del correo de PHP mail(). Con esto en su lugar, sin embargo, la implementación hook_mail_alter() se ha vuelto superflua ya que no hay encabezados que realmente estamos enviando a Mandrill (y el texto ya es HTML). Y para que el asunto bastante del trabajo del encargado del correo no se utiliza, pues no estamos pasando eso a Mandrill. Pero esto sólo tiene por objeto ilustrar el proceso de cómo se puede ir sobre la creación de este. Los detalles de la implementación dependen de usted y de sus necesidades.

Conclusión

Y ahí lo tenemos. Hemos implementado nuestro propio complemento de correo para ser utilizado por el d8module que iniciamos en el artículo anterior. Y debido a la naturaleza extensible de Drupal 8, ni siquiera tomar demasiado esfuerzo.

Lo que queda por hacer es perfeccionar la lógica de envío de correo y adaptarla a sus circunstancias. Esto puede significar una mayor integración entre Mandrill y tu instancia de Drupal, la construcción de buenas plantillas o lo que tienes. Además, una importante tarea restante es escribir pruebas automatizadas para esta funcionalidad. Y Drupal 8 ofrece el kit de herramientas para eso también.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.