Un plugin pour envoyer des emails avec une tâche Cron

Le plugin CronMailer est une solution facile à installer qui permet de gérer une file d’attente d’emails à envoyer par tâche Cron. Ce plugin a pour l’instant été testé avec la branche 1.3 de CakePHP. Le plugin inclut un composant EmailQueueComponent qui gère la file d’attente. Il fonctionne exactement comme le composant EmailComponent du coeur de Cake, à la différence près qu’il enregistre les emails dans la base de données au lieu de les envoyer aussitôt. Le plugin inclut également un Shell exécutable par la console de CakePHP, à lancer soit en ligne de commande, soit avec Crontab pour un envoi différé et par lot.

1. Installation

1.1 Fichiers

Pour installer le plugin, nous copions le répertoire cron_mailer dans le dossier plugins de notre application :

git clone git://github.com/kalt/cron-mailer.git cron_mailer

Nous pouvons aussi télécharger l’archive sur le compte Github et décompresser le dossier cron_mailer dans le dossier plugins.

1.2. Création de la table

Nous devons créer une nouvelle table dans la base de données, en appelant cette commande depuis la console :

cake schema create queue -plugin cron_mailer

Ou utiliser le fichier sql qui se trouve dans cron_mailer/config/sql/cron_mailer.sql.

2. Configuration

Imaginons une simple application de blog, dans laquelle nous souhaitons pouvoir alerter par email les utilisateurs inscrits dès qu’un nouveau post est publié. Si le nombre d’inscrit est trop grand, il se peut que l’hébergeur ne permette pas un envoi massif d’emails.

2.1 Le composant EmailQueueComponent

Au lieu d’utiliser le composant habituel pour envoyer des emails, nous allons appeler le composant fourni avec le plugin. Il se configure comme le composant du coeur, sauf pour le paramètre delivery qui doit valoir ‘db’.

class PostsController extends AppController {
	var $components = array('CronMailer.EmailQueue');
 
	function add()
	{
		// Ici la logique pour enregistrer le nouveau Post
		// ...
		if ($post = $this->Post->save()) {
			// On cherche tous les utilisateurs inscrits
			$this->loadModel('Subscriber');
			$subscribers = $this->Subscriber->find('all');
 
			// On transmet le contenu du nouveau Post aux vues de l'email
			$this->set('post', $post);
 
			// Configuration du composant
			$this->EmailQueue->to = Set::extract('/Subscriber/email', $subscribers);
			$this->EmailQueue->from = 'admin@exemple.com';
			$this->EmailQueue->subject = "Nouvel article : " . $post['Post']['title'];
			$this->EmailQueue->template = 'new_post';
			$this->EmailQueue->sendAs = 'both';
			$this->EmailQueue->delivery = 'db';
			$this->EmailQueue->send();
 
			// suite de l'action
		}
	}
}

Notons que s’il faut personnaliser le contenu de chaque email (« Bonjour {nom de l’utilisateur}, … »), il faut boucler sur la liste des destinataires et appeler la méthode $this->EmailQueue->reset() à la fin de la boucle.

2.2. Le CronMailer Shell

2.2.1. Configuration

Maintenant que la file d’attente des emails est remplie, nous allons configurer le Shell. Là encore, les options de configuration sont les mêmes que celles du composant EmailComponent du coeur, avec seulement un paramètre supplémentaire, limit qui représente le nombre d’emails qui seront envoyés à chaque exécution du Shell. Pour connaître cette limite, nous consultons la documentation de l’hébergeur.

La configuration du Shell se fait grâce à un fichier que nous allons créer ici : APP/config/cron_mailer.php, avec la structure suivante (nous le présentons ici avec toutes les options possibles et leurs valeurs par défaut) :

<?php
$config['CronMailer'] = array(
	'charset' => 'utf-8',
	'sendAs' => 'both',
	'delivery' => 'mail',
	'xMailer' => 'CakePHP Email Component',
	'filePaths' => array(),
	'smtpOptions' => array(
		'port'=> 25, 
		'host' => 'localhost', 
		'timeout' => 30
	),
	'messageId' => true,
	'limit' => 50,
);
?>

Cette étape est facultative, si les valeurs par défaut conviennent, il suffit de ne pas créer ce fichier.

2.2.2 Exécution du Shell

Nous pouvons à présent configurer Crontab pour qu’il lance la commande suivante à la périodicité désirée :

cake cron_mailer -app /chemin/complet/vers/app

Le lecteur trouvera plus d’informations dans le Cookbook pour exécuter des Shells en tâche Cron.

Pierre-Emmanuel Fringant

Articles connexes

Commentaires

[...] Un plugin pour envoyer des emails avec une tâche Cron [...]

Le cakePHP, c’est pas du gateau :)

Quelle est l’utilité du message_id ici ?

 'utf-8',
    'sendAs' =&gt; 'both',
    'delivery' =&gt; 'mail',
    'xMailer' =&gt; 'CakePHP Email Component',
    'filePaths' =&gt; array(),
    'smtpOptions' =&gt; array(
        'port'=&gt; 25, 
        'host' =&gt; 'localhost', 
        'timeout' =&gt; 30
    ),
    'messageId' =&gt; true,
    'limit' =&gt; 50,
);
?&gt;

Participez

Pour insérer une portion de code, utilisez <pre lang="php">...</pre>