[SOLVED] Form finisher differenet email recipients


(Matthias Lang) #1

Hey,

I’ve a contact form with a selection of the topic of the enquiry (general, application, technical problem, …). Is it possible to send an email via form finisher depending on the topic to different email addresses without rewriting the form finisher class?

Thanks,
Matthias


(Bastian Waidelich) #2

If you use the “static” YAML based form definition, that’s not possible I’m afraid.
With the Fusion based definition (Neos.Form.Builder) it would be possible.

But it’s just a few lines of PHP code to write a dedicated single purpose email finisher that gets the mapping topic => email address(es) via options.


(Matthias Lang) #3

Many thanks. I just rewrote the form with the Form Builder.

There’s one more question I couln’t find an answer with research:
How can I work with the submitted form values? Can i only get them with the curly braces like below or is there another way?
name = '{name}'


(Bastian Waidelich) #4

Work with them where?
In a finisher you can access them via the FinisherContext:

public function execute(FinisherContext $finisherContext): void
{
    $formValues = $finisherContext->getFormValues();
    // ...

(Matthias Lang) #5

I want to work with the variables directly in Fusion, that I can set the recipient address depending on a form value. Is this possible?


(Bastian Waidelich) #6

Oh, I think that was a misunderstanding, I’m sorry:
With the Fusion Builder you can create Form Definitions via Fusion.
They can be dynamic in that they can use Eel & access context variables like:

prototype(Some.Package:ContactForm) < prototype(Neos.Form.Builder:Form) {
    @context.redirectUri = Neos.Neos:NodeUri {
        node = ${q(node).property('redirectTarget')}
    }
    presetName = 'default'
    firstPage {
        // ...
    }
    finishers {
        redirectFinisher = Neos.Form.Builder:RedirectFinisher.Definition {
            options {
                uri = ${redirectUri}
            }
        }
    }
}

And you could use that to dynamically set the recipient(s) of the EmailFinisher based on the current context.
But that just creates a fixed Form definition in the end so it’s not possible to access the form values yet.

Your scenario is common so I think we should add some “recipientMapping” option to the existing EmailFinisher, but for now you’ll probably have to write your own.

You could just extend the existing one like

class MappingEmailFinisher extends EmailFinisher
{

    protected function executeInternal()
    {
        $this->options['recipientAddress'] = $this->resolveRecipient();
        parent::executeInternal();
    }

    private function resolveRecipient(): string
    {
        if (!empty($this->options['recipientMapping']) && is_array($this->options['recipientMapping']) && !empty($this->options['recipientMappingField'])) {
            $fieldValue = ObjectAccess::getPropertyPath($this->finisherContext->getFormValues(), $this->options['recipientMappingField']);
            if ($fieldValue !== null && array_key_exists($fieldValue, $this->options['recipientMapping'])) {
                return $this->options['recipientMapping'][$fieldValue];
            }
        }
        // TODO exception / default recipient?
    }
}

Or just create a new implementation of the FinisherInterface and copy/adjust the relevant code from the EmailFinisher.

HTH


(Matthias Lang) #7

Thanks for your reply, @bwaidelich!

I’ll try and hopefully succeed :grin:


(Bastian Waidelich) #8

Let me know if you get stuck!


(Bastian Waidelich) #10

@Matschess you deleted your last post before I had a chance to respond. Did you find a solution yourself?


(Matthias Lang) #11

Hey @bwaidelich,

in the end I decided to build the form with the Yaml form builder and make the addresses static in the Yaml configuration, becuase it’s not likely that they will change. But the mapping works well!

Very simple and familiar :grinning:
Screenshot

Thanks for the help, maybe we will se a “Recipient Mapping Class” in one of the future Neos versions :+1: