In your local bundles, you must create a configuration file defining the email contexts.
The location is: *Bundle/Resources/config/email-contexts.yml
The file must contain the key email-contexts as root.
Each context will have the name of its key in the context.
A context is definable with the following keys:
The data of a context (key data) is defined with the following keys:
The data of each context is defined in an associative array allowing to expose the properties (or methods) of objects having the @Reportable annotation (ValueIn\CommonBundle\Annotation\Reportable).
For example, we need to display the username of the current user in the email : we will define the tokenEntities key in this way:
email-contexts:
product-added-to-cart:
data:
tokenEntities:
user: AppBundle\Entity\User
From the @Reportable annotation the visual editor will display an auto-completion listing the visible elements of the object in question:
You may not have the possibility to add these annotations on entities (or any kind of object) of the generic.
In this case, you simply need to set up a decorator for the object and apply the @Reportable annotation to the getters of this decorator.
Example: The entity AppBundleEntityProduct has no @Reportable annotation. We create the following decorator:
use ValueIn\CommonBundle\Annotation\Reportable;
class ProductInformation
{
/**
* @var Product
*/
private $product;
public function __construct(
Product $product
) {
$this->product = $product;
}
/**
* @Reportable("Title")
*
* @return string
*/
public function getTitle(): string
{
return $this->product->getTitle();
}
}
When calling the email service, we will pass this decorator as a parameter so that the types of the tokenEntities are valid (see the usage example)
email-contexts:
product-added-to-cart:
subject: Your added a product to your cart
fromAddress: no-reply@your-shop.com
textBody: |
Hello [[user.username]],
You added product [[product.title]] into your cart.
Here some detailed informations about this product :
{% for attr in product.attributes %}
- {{ attr.name }}: {{ attr.value }}
{% endfor %}
htmlBody: |
<p>Hello [[user.username]],</p>
<p>You added product <b>[[product.title]]</b> into your cart.</p>
<p>Here some detailed informations about this product :</p>
<ul>
<li class="productAttribute">
<b>[[productAttribute.name]] : </b>
[[productAttribute.value]]
</li>
</ul>
data:
tokenEntities:
user: AppBundle\Entity\User
product: Local\EmailBundle\Model\Template\Email\ProductInformation
productAttribute: Local\EmailBundle\Model\Template\Email\ProductAttributeInformation
loopEntities:
-
key: productAttribute
from: product.attributes
label: Product Attribute
types:
- li
color: hsl(195, 53%, 79%)
Contexts are loaded in this order of priority:
Contexts are defined in the generic application.
It is possible to overload these contexts by redefining them in your local bundles.
The overloading is done with the array_replace_recursive function.
You can also overload contexts defined in local bundles, provided that the overloading is done in the correct order of priority. (ABundle will not be able to override contexts from BBundle, but the reverse will be possible).
From the symfony logger, it is possible to check the loading of contexts. The loading order is chronological and the final merge is displayed last.
The AppBundle\Service\EmailSender allows to send an email for a given context.
The method to call is sendEmailFromTemplate(string $templateName, string $to, ?string $toName, array $params = []): void
$templateName is the name of the context you defined, $to is the destination email address. The optional $toName parameter allows you to assign a name to the email address and the array $params is the array of variables that will be used in the rendering of the email body.
$this->emailSender->sendEmailFromTemplate('product-added-to-cart', $user->getEmail(), $user->getUsername(), [
'user' => $user,
'product' => new ProductInformation($event->getProduct()),
'productAttribute' => new ProductAttributeInformation,
]);