D8 Emails - pierregermain/MyDrupal GitHub Wiki

Envío de emails

hook_mail()

hook_mail ($key, &$message, $params)

donde:

  • $key Cadena de texto que servirá para identificar al email, ya que una misma función hook_mail() puede implementar varios emails.
  • $message array con los siguientes elementos:
    • id: Identificador del correo mandado: {$module}_{$key}, es computado automáticamente
    • to: Destinatarios separados por comas (,)
    • subject
    • body: Es un array. Puede contener líneas de texto o objetos tipo Markup
    • from
    • headers
  • $params

Ejemplo:

Hook:

/**
 * Implements hook_mail().
 */
function mymodule_mail($key, &$message, $params) {
  $options = [
    'langcode' => $message['langcode'],
  ];
  switch ($key) {
    case 'contact_message':
      $username = \Drupal::currentUser()->getDisplayName();
      $message['from'] = \Drupal::config('system.site')->get('mail');
      $site_name = \Drupal::config('system.site')->get('name');
      $message['subject'] = t('E-mail sent from @site-name',
        ['@site-name' => $site_name], $options);
      $message['body'][] = t('@name sent you the following
message:', ['@name' => $username], $options);
      $message['body'][] = MailFormatHelper::htmlToText($params['message']);
      break;
  }
}

Formulario

mymodule.message:
  path: '/mymodule/email/message'
  defaults:
    _form: '\Drupal\mymodule\Form\MymoduleMessageForm'
  requirements:
    _role: 'authenticated'
<?php

namespace Drupal\mymodule\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Egulias\EmailValidator\EmailValidator;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MymoduleMessageForm extends FormBase {

  protected $mailManager;

  protected $languageManager;

  protected $emailValidator;

  public function __construct(MailManagerInterface $mail_manager,
                              LanguageManagerInterface $language_manager,
                              EmailValidator $email_validator) {
    $this->mailManager = $mail_manager;
    $this->languageManager = $language_manager;
    $this->emailValidator = $email_validator;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('plugin.manager.mail'),
      $container->get('language_manager'),
      $container->get('email.validator')
    );
  }

  public function getFormId() {
    return 'mymodule_message_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['intro'] = [
      '#markup' => t('Use this form to send a message to an e-mail
address'),
    ];
    $form['message_to'] = [
      '#type' => 'email',


      '#title' => $this->t('E-mail address'),
      '#required' => TRUE,
    ];
    $form['message'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Message'),
      '#required' => TRUE,
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];
    return $form;
  }

  public function validateForm(array &$form, FormStateInterface $form_state) {
    $email = $form_state->getValue('message_to');
    if (!$this->emailValidator->isValid($email)) {
      $form_state->setErrorByName('message_to', $this->t('%email
is not a valid email address.', ['%email' => $email]));
    }
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    // elimina elementos internos y botones de $form_state
    $form_values = $form_state->cleanValues()->getValues();
    $module = 'mymodule';
    $key = 'contact_message';
    $to = $form_values['message_to'];
    $params = $form_values;
    $language_code = $this->languageManager->getDefaultLanguage()->getId();
    $send_now = TRUE;
    // Llamada a Mail Manager para mandar el mail
    $result = $this->mailManager->mail($module, $key, $to,
      $language_code, $params, NULL, $send_now);
    if ($result['result'] == TRUE) {
      drupal_set_message($this->t('Your message has been sent.'));
    }
    else {
      drupal_set_message($this->t('There was a problem sending
your message and it was not sent.'), 'error');
    }
  }

}

plugin Mail Manager

Es el que envía el email y rellena variables / datos (por ejemplo el destinatario)

  • servicio 'plugin.manager.mail'
  • se puede meter en un submit por ejemplo
MailManager::mail($module, $key, $to, $langcode, $params = array(), $reply = NULL, $send = TRUE)

donde:

  • $module. Es el identificador que se pasa al hook
  • $key. Identificador (igual que en el hook)
  • $to Formatos posibles:
  • $langcode. Valores posibles:
    • $account->getPreferredLangcode(): Idioma del destinatario
    • \Drupal::currentUser()->getPreferredLangcode(): Idioma del usuario actual en el site
    • \Drupal::languageManager()->getDefaultLanguage()->getId(): Idioma neutral
  • $params. Opcional. Por medio de $params podemos compartir información entre el método mail() y hook_mail().
  • $reply. Opcional. Suele tener el valor de $from
  • $send. S epone a TRUE para que se mande el email.

esto devuelve un array con el resultado de la operación.

hook_mail_alter()

  • permite modificar los mensajes de email antes de ser enviados.
  • Cualquier módulo puede interactuar con un mensaje antes de ser enviado, siempre que conozca su identificador (sigue el patrón '$module_$key').
hook_mail_alter (&$message)

El parámetro $message solicitado por la función hook_mail_alter() será un array estructurado con los mismos campos que los del parámetro $message en hook_mail(). A su vez se corresponde con el array $message devuelto por MailManager::mail(). El parámetro $message se pasa a la función por referencia, para que pueda ser modificado por cualquier módulo.

Ejemplo: incluir una línea adicional al final del mensaje que indica el nombre del sitio desde donde se envió el correo.

/**
 * Implements hook_mail_alter().
 */
function mymodule_mail_alter(&$message) {
  if ($message['id'] == 'contact_page_mail') {
    $site_name = \Drupal::config('system.site')->get('name');
    $signature = t("\n--\nMail altered by email_example module.",
      [], $options);
    $message['body'][] = t("Mail sent out from @site-name",
      ['@site-name' => $site_name]);
  }
}