eZ Platform Discussions

eZ EE Send custom mail on submission


#1

Good morning, everyone.

For once I don’t create a topic because I’m in trouble but because I’m rather proud to share my find.

My purpose is to send a notification email to the submission of a form based on the data entered.

The form has a “Subject” field of type select.
Depending on this choice, the email address to be notified is not the same.

Les mails de notification sont envoyés par le service EzSystems\EzPlatformFormBuilder\FormSubmission\Notification\EmailNotificationSender.
On va donc le Décorer.

services:
    MyBundle\EmailNotificationSender:
        # https://symfony.com/doc/3.4/service_container/service_decoration.html
        # overrides the EzSystems\...\EmailNotificationSender service
        # but that service is still available as ... (@see decoration_inner_name)
        decorates: EzSystems\EzPlatformFormBuilder\FormSubmission\Notification\EmailNotificationSender

        decoration_inner_name: MyBundle\FormBuilder\EmailNotificationSender.inner

        arguments:
            - "@mailer"
            - "@twig"
            - '@@ezdesign/form_builder/form_submit_notification_email.html.twig'

        # private, because usually you do not need to fetch  directly
        public:    false

    # https://symfony.com/doc/3.4/service_container/alias_private.html#aliasing
    EzSystems\EzPlatformFormBuilder\FormSubmission\Notification\EmailNotificationSender:
        alias: MyBundle\FormBuilder\EmailNotificationSender
        public: true

Note. We pass on to our service the same arguments as those passed on to the original service because we are going to make a legacy…

namespace MyBundle;

use eZ\Publish\API\Repository\Values\Content\Content;
use eZ\Publish\Core\FieldType\Author\Author;
use EzSystems\EzPlatformFormBuilder\FieldType\Model\Field;
use EzSystems\EzPlatformFormBuilder\FieldType\Model\Form;
use EzSystems\EzPlatformFormBuilder\FieldType\Model\FormSubmission;
use \EzSystems\EzPlatformFormBuilder\FormSubmission\Notification\EmailNotificationSender as EzEmailNotificationSender;
use EzSystems\EzPlatformFormBuilder\FormSubmission\Notification\NotificationSenderInterface;

class EmailNotificationSender extends EzEmailNotificationSender implements NotificationSenderInterface
{
    /** @var \Swift_Mailer */
    private $mailer;

    /** @var \Twig_Environment */
    private $twig;

    /** @var string */
    private $emailTemplate;

    public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig, $emailTemplate)
    {
        parent::__construct($mailer, $twig, $emailTemplate);
        $this->twig = $twig;
        $this->mailer = $mailer;
        $this->emailTemplate = $emailTemplate;
    }

    public function sendNotification(Content $content, Form $form, FormSubmission $data, Field $field): void
    {
        $recipients = $this->getRecipients($content, $form, $data);
        if ($recipients) {
            $this->doSendEmail($recipients, [
                'content' => $content,
                'form' => $form,
                'data' => $data,
            ]);
        }

        parent::sendNotification($content, $form, $data, $field); // Default ez mail.
    }

    private function getRecipients(Content $content, Form $form, FormSubmission $data)
    {
        // Do What you have to do
        return $recipients;
    }

    /**
     * Je suis obligé de recopier mot pour mot cette fonction car elle est privée. :(
     *
     * @param string[] $recipients
     * @param string[] $parameters
     *
     * @throws \Twig_Error_Loader
     * @throws \Twig_Error_Runtime
     * @throws \Twig_Error_Syntax
     */
    protected function doSendEmail(array $recipients, array $parameters = []): void
    {
        $template = $this->twig->loadTemplate($this->emailTemplate);
        $message = new \Swift_Message();
        $message->setSubject($template->renderBlock('subject', $parameters));
        $message->setTo($recipients);
        $message->setFrom('no-reply@editionsduboisbaudry.fr');
        $message->setBody($template->renderBlock('body', $parameters), 'text/html');
        $this->mailer->send($message);
    }
}

There you go!
When submitting the form we will be able to search for recipients for the notification email in the getRecipients function.
Note: The default behavior is retained.


#2

As far as I’m concerned. I have in my form a subject_dest field which is a copy of the dropdown

ez_platform_form_builder:
    fields:
        subject_dest:
            name: 'Subject'
            thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#dropdown'
            attributes:
                help:
                    name: 'Help'
                    type: 'string'
                options:
                    name: 'Options'
                    type: 'choices'
            validators:
                required: ~

And in my Form ContentType I have an Author field. (form_subject_dest)

And if there is a match between the value entered by the Internet user in the subject_dest field and the name of an author, we have a recipient.

    private function getRecipients(Content $content, Form $form, FormSubmission $data)
    {
        /** @var \Ez\Publish\Core\FieldType\Author\Value $fv */
        $fv = $content->getFieldValue('form_subject_dest');

        $recipients = [];

        $selected_value = null; // La valeur sélectionnées dans le champ de type 'select_value' par l'Internaute.
        foreach ($data->getValues() as $value) {
            if ($value->getIdentifier() === 'subject_dest') {
                $selected_value = $value->getValue();
                if ($selected_value) {
                    break;
                }
            }
        }

        foreach ($fv->authors as $author) {/** @var Author $author */
            if ($author->name === $selected_value) {
                $recipients[] = $author->email;
            }
        }

        return $recipients;
    }

It’s a little bit of DIY, but it works.

The best would be to have a form field that does all this… But now I’m tired…


#3

Nice! Just a note to anyone implementing getRecipients(), don’t read them from the submitted form, because then you’ll have created an engine for anonymous spam sending :wink: