Newsletter Apprendre Laravel #4

Envoyée le 27 janvier 2019

Bienvenue dans la 4e newsletter d'Apprendre Laravel !

Bibliothèque

Vous ne le saviez peut-être pas, mais Mailgun et Sendgrid ne sont pas que des services d'envoi de mails, vous pouvez également recevoir des mails via ces services et les traiter automatiquement. Par exemple, si vous avez une adresse de contact ou de support pour votre produit, vous pouvez automatiquement créer un enregistrement en base de données à chaque nouveau mail reçu pour améliorer la traçabilité.

Beyond Code a sorti cette semaine un nouveau package : Laravel Mailbox https://docs.beyondco.de/laravel-mailbox/ qui permet de simplifier ce processus. Les mails reçus sont automatiquement stockés dans votre base de données et vous pouvez écouter la réception de mail pour réagir d'une manière ou d'une autre.

Si vous n'utilisez pas ces services mais un serveur de mail personnel Postfix, vous pouvez aussi utiliser la très bonne bibliothèque https://github.com/php-mime-mail-parser/php-mime-mail-parser qui permet de faire « presque » la même chose, mais sans dépendre d'un service tiers.

Teasing

Marcel Pociot, qui vient de sortir la bibliothèque Laravel Mailbox décrite plus haut, a également annoncé sur Twitter qu'il avait encore 4 autres bibliothèques en préparation.

https://twitter.com/marcelpociot/status/1088115153151893504

Au vu du niveau de Laravel Websocket et Laravel Mailbox, cela promet des outils supplémentaires très intéressants pour l'éco-système Laravel. À suivre.

Morceau de code

Cette semaine, Taylor a évoqué comment rendre certaines parties de notre code idempotent pouvait améliorer la lisibilité et la facilité d'utilisation.

Premièrement, qu'est-ce qu'un code idempotent ? C'est un code qui, s'il est exécuté plusieurs fois de suite, délivrera le même résultat. Par exemple, l'exemple suivant n'est pas idempotent :

Article::create([
    'titre' => 'Mon titre',
    'contenu' => 'Mon contenu',
]);

Si nous exécutons plusieurs fois ce code, plusieurs articles seront créés en base de données.

L'avantage d'un code idempotent, surtout dans les queues Laravel ou dans les webhooks de services tiers, c'est qu'en cas de problème, la queue peut relancer le code ou le service tiers peut rappeler le webhook sans craindre de casser quelque chose.

Un exemple plus concret. Lorsque Stripe valide le paiement d'un abonnement via un webhook nous pouvons faire quelque chose du genre :

$payment = Payment::create([
    'user_id' => $stripePayment->user_id,
    'amount' => $stripePayment->amount,  
]);

Mail:to($stripePayment->user_email)->send(new PaymentReceived($payment));

Mais si un problème survient lors de l'envoi du mail, Stripe va remarquer que le webhook a échoué et va essayer de rappeler l'URL. Nous aurons alors deux paiements créés en base de données. Nous pouvons résoudre ce problème en rendant notre code idempotent :

$payment = Payment::updateOrCreate([
    'stripe_payment_id' => $stripePayment->id,
    'user_id' => $stripePayment->user_id,
    'amount' => $stripePayment->amount,  
], ['stripe_payment_id' => $stripePayment->id]);

Mail:to($stripePayment->user_email)->send(new PaymentReceived($payment));

Dans ce cas la fonction updateOrCreate va d'abord vérifier si un paiement n'existe pas dans la base de données avec cet identifiant Stripe. S'il existe, Laravel va le mettre à jour, si il n'existe pas, Laravel va le créer pour nous. Ensuite, nous pouvons envoyer le mail.

D'autres astuces existent pour rendre notre code idempotent comme l'utilisation des transactions SQL (en cas d'exception, la base de données est restaurée à son état d'origine), ou l'utilisation des attributs Eloquent wasRecentlyCreated ou exists pour savoir si le modèle a été créé durant cette requête ou existe en base de données.

Question de la semaine

Cette semaine nous étudions une question sur le Discord à propos de Carbon. Carbon est une bibliothèque de gestion de date qui est beaucoup utilisée par le framework Laravel mais qui n'est pas développée par Laravel. Vous pouvez trouver la documentation sur https://carbon.nesbot.com/docs/.

Lorsque vous recevez une chaîne de caractère représentant une date d'un formulaire vous ne pouvez l'enregistrer en base de données que si elle est dans le bon format "2019-01-27 12:00:00". Si ce n'est pas le cas, vous pouvez utiliser une date Carbon et Laravel se chargera automatiquement de la convertir dans le bon format lors de l'enregistrement.

// exemple: request('date') = '27/01/2019';

Evenement::create([
    'title' => request('title'),
    'date_de_l_evenement' => Carbon::createFromFormat('d/m/Y', request('date'));
]);

À l'inverse lorsque vous récupérez votre modèle depuis la base de données, Laravel va vous retourner une chaîne de caractère par défaut :

$evenement = Evenement::find(1);
$evenement->date; // "2019-01-27"
$evenement->date->isFuture();
// Erreur : vous essayez d'appeler la fonction `isFuture` sur une chaîne de caractère

Si vous souhaitez avoir un objet Carbon pour pouvoir utiliser toutes les méthodes pratiques de cette bibliothèque, vous pouvez le dire à Laravel via l'attribut $dates de votre modèle.

class Evenement extends Model
{
    protected $dates = ['date_de_l_evenement'];
}

$evenement = Evenement::find(1);
$evenement->date; // "2019-01-27"
$evenement->date->isFuture();
// Fonctionne : renvoie vrai ou faux en fonction de la date du jour.

Apprendre Laravel

La chaîne YouTube vient de passer les 1000 abonnés. Les vidéos reprendront au rythme d'une par semaine début février avec des vidéos sur VueJS & API Laravel. N'hésitez pas à me dire en réponse à ce mail ce que vous attendez de cette série et ce que vous aimeriez y voir !

Comme toujours, vous pouvez répondre à ce mail pour me faire vos retours, poser vos questions ou me demander de vous retirer de la liste.

Bon dimanche après-midi,

Thibaud