Email Template Dev
Usage
Definition of contexts
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:
subject: The default subject of the email
fromAddress: The default send address
textBody: The default plain-text content
htmlBody: The default HTML content
data {exclamation-triangle icon} required: The list of data in the context
The data of a context (key data) is defined with the following keys:
tokenEntities: Associative array of available replacement tokens in the email body, variable name => type
loopEntities: List of available loop structures (see Quotes template operation for more info)
Context data
The data of each context is defined in an associative array allowing to expose the properties (or methods) of objects having the @Reportable annotation (ValueInCommonBundleAnnotationReportable).
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)
Example of a context
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%)
Priority of loading
Contexts are loaded in this order of priority:
generic contexts
local bundle contexts, in ascending alphabetical order by bundle name (TestBundle will be loaded before ZooBundle)
NOTE: The local bundle must implement the AppBundleInterfacesSwitchable interface and the isEnabled method must return true for the configuration to be taken into account.
Overloading and merging of contexts
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).
Debugger
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.
Use of the e-mail service
The AppBundleServiceEmailSender 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.
Example
$this->emailSender->sendEmailFromTemplate('product-added-to-cart', $user->getEmail(), $user->getUsername(), [ 'user' => $user, 'product' => new ProductInformation($event->getProduct()), 'productAttribute' => new ProductAttributeInformation,]);