Utiliser et étendre l'API Drupal 8 Mail 1ère partie

Dans cette série de deux parties, nous allons explorer l'API Mail dans Drupal 8. Ce faisant, nous allons couvrir deux aspects principaux: comment l'utiliser de manière programmée pour envoyer des emails et comment l'étendre pour utiliser un service externe comme Mandrill.

Pour démontrer cela, nous allons créer un email personnalisé dans la première partie modèle qui s’utilise pour envoyer des courriers électroniques à l’utilisateur actuel lorsqu’il enregistre un nouveau nœud Article. De plus, nous verrons comment d’autres peuvent modifier cela. modèle afin de permettre le rendu HTML du corps de l'e-mail au lieu du texte brut par défaut.

Dans la deuxième partie, nous examinerons l’extension du système de messagerie et l’intégration d’une API externe pour la remise des messages. Pour cela, nous utiliserons Mandrill et sa bibliothèque PHP qui fournit une bonne base pour interagir avec son API..

Tout le travail que nous accomplissons se trouve dans ce référentiel Git dans le cadre d’un module personnalisé Drupal 8 que nous allons commencer à écrire ici. Alors n'hésitez pas à vérifier si vous voulez suivre. Commençons.

La première condition préalable de ce module est sa .Info fichier:

d8mail.info.yml:

name: Drupal 8 Mailer description: 'Montre l'utilisation de l'API Mail dans Drupal 8.' noyau: type 8.x: module 

Cela fait, nous pouvons déjà activer le module sur notre site si nous voulons.

Comment envoyons-nous un courriel??

Pour programmer un e-mail avec Drupal 8, vous devez suivre deux étapes principales. Nous devons d’abord implémenter hook_mail () afin de définir un ou plusieurs e-mails. des modèles. La deuxième étape consiste à utiliser le gestionnaire de messagerie pour envoyer des courriels à l’aide de l’un de ces des modèles.

Bien appelé crochet, hook_mail () Ce n'est pas un crochet typique mais plutôt une fonction régulière qui est généralement appelée uniquement par le même module qui l'implémente. En d’autres termes, lorsque vous envoyez un courrier électronique par programme, vous devez spécifier le nom du module hook_mail () et le modèle id que vous voulez utiliser et qui est défini par ce hook. Mais nous verrons cela dans une minute. Tout d'abord, comment pouvons-nous le mettre en œuvre?

d8mail.module:

/ ** * Implémente hook_mail (). * / function d8mail_mail ($ key, & $ message, $ params) $ options = array ('langcode' => $ message ['langcode'],); switch ($ key) case 'node_insert': $ message ['from'] = \ Drupal :: config ('system.site') -> get ('mail'); $ message ['subject'] = t ('Noeud créé: @title', tableau ('@ title' => $ params ['node_title']), $ options); $ message ['body'] [] = SafeMarkup :: checkPlain ($ params ['message']); Pause;  

Ceci est une implémentation très simple qui définit un modèle identifiée en tant que node_insert (la clé $). Les deux autres arguments de la fonction sont:

  • $ message: passé par référence, et à l'intérieur duquel nous ajoutons autant de détails sur notre courrier électronique que nécessaire 
  • $ params: un tableau de données supplémentaires devant être insérées dans le courrier électronique et transmises par le gestionnaire de messagerie lorsque nous essayons d'envoyer le courrier électronique

Comme vous pouvez le constater, nous construisons le $ message tableau avec des valeurs que nous voulons que cet email inclue dans tous les appels. Nous établissons une valeur par défaut de valeur extraite du système de configuration et représentant l'adresse électronique du site principal. Nous définissons un email passe-partout assujettir qui permet au destinataire de savoir qu'un nouveau nœud a été créé, suivi du nom du nœud (qui sera transmis via le $ params tableau). Le sujet est également traduisible dans la langue transmise par l'appelant. 

Enfin, nous courons le message corps Le texte peut contenir du code HTML et le texte peut être tronqué si nous ne codons pas les éléments HTML. Et puisque nous utilisons le SafeMarkup classe, nous devons utilisation en haut:

utilisez Drupal \ Component \ Utility \ SafeMarkup; 

De plus, le corps du message est un tableau qui sera plus tard implosé dans une chaîne. Et bien sûr, il y a beaucoup d'autres paramètres que nous pouvons définir, tels que les en-têtes, mais cela suffira pour cet exemple..

Et c'est tout pour le hook_mail () la mise en oeuvre. Passons maintenant au code qui est exécuté à chaque fois qu'un nouveau noeud est créé, hook_entity_insert ():

/ ** * Implémente hook_entity_insert (). * / function d8mail_entity_insert (Drupal \ Core \ Entity \ EntityInterface $ entity) if ($ entity-> getEntityTypeId ()! == 'noeud' || ($ entity-> getEntityTypeId () === 'noeud' && $ $ entité -> bundle ()! == 'article')) return;  $ mailManager = \ Drupal :: service ('plugin.manager.mail'); $ module = 'd8mail'; $ key = 'node_insert'; $ to = \ Drupal :: currentUser () -> getEmail (); $ params ['message'] = $ entity-> get ('body') -> valeur; $ params ['node_title'] = $ entity-> label (); $ langcode = \ Drupal :: currentUser () -> getPreferredLangcode (); $ send = true; $ result = $ mailManager-> mail ($ module, $ clé, $ à, $ langcode, $ params, NULL, $ send); if ($ result ['result']!! == true) $ message = t ('Un problème est survenu lors de l'envoi de votre notification par courrier électronique à @email pour la création du noeud @id.', array ('@ email' => $ to , '@id' => $ entity-> id ())); drupal_set_message ($ message, 'error'); \ Drupal :: logger ('d8mail') -> error ($ message); revenir;  $ message = t ('Une notification par courrier électronique a été envoyée à @email pour la création du noeud @id.', array ('@ email' => $ to, '@id' => $ entity-> id ())) ; drupal_set_message ($ message); \ Drupal :: logger ('d8mail') -> notice ($ message);  

Ce hook est déclenché après chaque sauvegarde de nœud et tout ce que nous avons à faire est de nous assurer de cibler le bon nœud et d'inclure notre logique..

Après avoir vérifié que l'entité de noeud est du type article, nous chargeons le service de gestion du courrier Drupal et commençons à définir des valeurs pour l’e-mail. Nous avons besoin des informations suivantes:

  • le nom du module qui implémente hook_mail () et définit notre modèle (ce que j'ai mentionné ci-dessus)
  • la modèle id (le clé $)
  • l'adresse e-mail du destinataire (celle qui figure sur le compte d'utilisateur actuel)
  • la langue ($ langcode) qui va à l'intérieur du $ params tableau et qui sera utilisé pour traduire le message sujet
  • le titre du nœud qui sera ajouté à l'objet de l'e-mail
  • le corps de l'e-mail, qui dans notre cas sera la valeur du champ de corps du noeud
  • la valeur booléenne indiquant si l'e-mail doit être réellement envoyé

Nous passons ensuite toutes ces valeurs au courrier() méthode du gestionnaire de messagerie. Ce dernier est responsable de la construction du courrier électronique (en appelant le bon hook_mail () l’implémentation en est un aspect) et enfin, déléguer la livraison effective au plugin responsable. Par défaut, ce sera PHPMail, qui utilise le paramètre par défaut. courrier() fonction fournie avec PHP.

Si le gestionnaire de messagerie réussit à envoyer le courrier électronique (la livraison réelle n'est pas prise en compte, mais plutôt une action réussie de PHP), la commande courrier() la méthode retournera un tableau contenant un résultat clé avec le retour du plugin mail. En vérifiant cette valeur, nous pouvons savoir si l'action de courrier électronique a abouti et informer l'utilisateur que nous lui avons informé de son action. Sinon, nous imprimons et enregistrons un message d'erreur.

Et c'est à peu près tout. Effacer le cache et créer un nœud d'article devrait vous envoyer un email dans votre boîte de réception. Si vous n'obtenez rien et qu'il n'y a pas de signe d'erreur sur votre écran, vérifiez les journaux de votre serveur et votre file d'attente pour vérifier que les courriels sont envoyés..

Avant de poursuivre, je voudrais faire une petite note concernant cette implémentation de hook. Dans cet exemple, j'ai placé toute la logique à l'intérieur directement. De plus, j'ai utilisé un retour anticipé en haut, ce qui signifie essentiellement qu'aucune autre logique ne peut être ajoutée, à l'exception de celle spécifique aux noeuds d'article. Dans les applications réelles, je recommande de refactoriser la logique de mailing dans une fonction ou une classe séparée et de passer à cela. De plus, vous ne devez pas utiliser les retours anticipés dans les implémentations de hook, mais appeler d'autres fonctions si les conditions sont remplies.. 

Comment pouvons-nous modifier un courriel?

Une fois que tout cela est en place, nous avons un autre outil à notre disposition qui nous permet de modifier une telle configuration existante: hook_mail_alter (). Ce hook est appelé depuis le gestionnaire de messagerie avant que le plug-in de messagerie responsable n'envoie l'e-mail. Le but est de permettre à d’autres modules d’apporter des modifications finales à un courrier électronique existant envoyé.

Bien que cela puisse également être utilisé par d'autres modules, nous allons illustrer un exemple d'implémentation à partir du même module que celui avec lequel nous avons travaillé. À cette fin, nous modifierons l’email en modifiant l’un de ses en-têtes par défaut afin de le transformer du texte brut en HTML. Et voici comment nous pouvons le faire:

/ ** * Implémente hook_mail_alter (). * / function d8mail_mail_alter (& $ message) switch ($ message ['clé']) case 'node_insert': $ message ['en-têtes'] ['Content-Type'] = 'text / html; jeu de caractères = UTF-8; format = coulé; delsp = yes '; Pause;  

Comme vous pouvez le constater, il s’agit d’une simple modification du Type de contenu en-tête qui transforme l'e-mail en HTML. De cette façon, les entités HTML en texte brut seront analysées au format HTML par les clients de messagerie. Et en utilisant le boîtier de commutation, nous nous assurons que cela ne se produit que pour le courrier électronique. modèle nous avons défini plus tôt.

Une chose à noter ici est que l’alter hook est appelé après le message correspondant. hook_mail () la mise en oeuvre. Ainsi, après cela, le seul traitement qui se produit sur le courrier électronique est effectué à l'intérieur du format() méthode du plugin mail (imposée par son interface).

Conclusion

Et c'est à peu près tout ce qu'il y a à envoyer des emails à l'aide de Drupal 8 à des fins de programmation. des modèles que le gestionnaire de courrier s'hydrate chaque fois que nous le voulons. Nous avons également mentionné le plug-in de livraison du courrier par défaut utilisé pour envoyer des courriers électroniques dans Drupal 8. Enfin, nous avons vu comment d'autres modules peuvent maintenant modifier notre courrier électronique en ajoutant de nouveaux en-têtes, en modifiant le sujet, en concaténant des valeurs dans le corps du courrier. , etc.

Dans le prochain article, nous allons remplacer le plug-in PHPMail par défaut par notre propre implémentation personnalisée. Nous allons configurer un mailer qui utilise Mandrill avec l'aide de sa bibliothèque PHP. L’objectif est de permettre à notre propre module d’utiliser cette messagerie alors que le reste de l’application continue à utiliser le logiciel par défaut PHPMailer..