How to send a custom e-mail?¶
Note
This cookbook is suitable for a clean sylius-standard installation. For more general tips, while using SyliusMailerBundle go to Sending configurable e-mails in Symfony Blogpost.
Currently Sylius is sending e-mails only in a few “must-have” cases - see E-mails documentation. Of course these cases may not be sufficient for your business needs. If so, you will need to create your own custom e-mails inside the system.
On a basic example we will now teach how to do it.
Let’s assume that you would like such a feature in your system:
Feature: Sending a notification email to the administrator when a product is out of stock
In order to be aware which products become out of stock
As an Administrator
I want to be notified via email when products become out of stock
To achieve that you will need to:
1. Create a new e-mail that will be sent:¶
- prepare a template for your email in the
templates/Email
.
{# templates/Email/out_of_stock.html.twig #}
{% block subject %}
One of your products has become out of stock.
{% endblock %}
{% block body %}
{% autoescape %}
The {{ variant.name }} variant is out of stock!
{% endautoescape %}
{% endblock %}
- configure the email under
sylius_mailer:
in theconfig/packages/sylius_mailer.yaml
.
# config/packages/sylius_mailer.yaml
sylius_mailer:
sender:
name: Example.com
address: [email protected]
emails:
out_of_stock:
subject: "A product has become out of stock!"
template: "Email/out_of_stock.html.twig"
2. Create an Email Manager class:¶
- It will need the EmailSender, the AvailabilityChecker and the AdminUser Repository.
- It will operate on the Order where it needs to check each OrderItem, get their ProductVariants and check if they are available.
<?php
namespace App\EmailManager;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface;
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
final class OutOfStockEmailManager
{
/** @var SenderInterface */
private $emailSender;
/** @var AvailabilityCheckerInterface */
private $availabilityChecker;
/** @var RepositoryInterface $adminUserRepository */
private $adminUserRepository;
public function __construct(
SenderInterface $emailSender,
AvailabilityCheckerInterface $availabilityChecker,
RepositoryInterface $adminUserRepository
) {
$this->emailSender = $emailSender;
$this->availabilityChecker = $availabilityChecker;
$this->adminUserRepository = $adminUserRepository;
}
public function sendOutOfStockEmail(OrderInterface $order): void
{
// get all admins, but remember to put them into an array
$admins = $this->adminUserRepository->findAll()->toArray();
foreach ($order->getItems() as $item) {
$variant = $item->getVariant();
$stockIsSufficient = $this->availabilityChecker->isStockSufficient($variant, 1);
if ($stockIsSufficient) {
continue;
}
foreach ($admins as $admin) {
$this->emailSender->send('out_of_stock', [$admin->getEmail()], ['variant' => $variant]);
}
}
}
}
3. Register the manager as a service:¶
# config/packages/_sylius.yaml
services:
App\EmailManager\OutOfStockEmailManager:
arguments: ['@sylius.email_sender', '@sylius.availability_checker', '@sylius.repository.admin_user']
4. Customize the state machine callback of Order’s Payment:¶
# config/packages/_sylius.yaml
winzou_state_machine:
sylius_order_payment:
callbacks:
after:
app_out_of_stock_email:
on: ["pay"]
do: ["@app.email_manager.out_of_stock", "sendOutOfStockEmail"]
args: ["object"]
Done!