I've updated the information below to work with Craft 3.7
I wanted to allow people to chose which person/department to send a message to using the P&T Contact Form plugin. I've seen one method to do this, eg:
<select name="toEmail">
<option value="{{ '[email protected]'|hash }}">1st name</option>
<option value="{{ '[email protected]'|hash }}">2nd name</option>
</select>
but it does mean that the actual email address is visible in the HTML code. Which would allow the spam robots to harvest it. Although it may be that the hash added makes it harder?
In the ideal world I would like the address to be completely hidden or encrypted in the form page html. I wondered if the name="toEmail" value=" " could be a variable that is passed along with the value="contactForm/sendMessage" action, that could then be referenced and replaced from a list in the contact form config file.
It seems to me that not having plain text email addresses should be the standard way of working so I'm surprised that there isn't already a plugin or method to do this, but I couldn't find one.
Edit to show the final solution I'm using.
I'm very grateful to Robin Schambach, who provided all the clever code, I've just put it all together here to help anyone looking for a similar solution. The email addresses are never available or visible on the front end.
I created a Section named Contacts with plain text data fields of:
contactName
contactPosition
contactEmail
contactKey (this stores the name in camelCase, so "johnSmith" not "John Smith") I use the preparse plugin to auto generate this.
This allows the end user to maintain/update the names and addresses of contacts without the developer needing to make changes on the server.
Install P&T Contact form plugin and add a config file to overide the plugin settings. The contents of that file should be:
<?php
$request = Craft::$app->request;
if (!$request->getIsConsoleRequest()) {
$toEmailId = $request->getBodyParam('toEmail');
// the rest of the configuration code goes here
$criteria = \craft\elements\Entry::find()
->section('contacts')
->all();
$allAddresses = [];
foreach($criteria as $entry){
$allAddresses[$entry->contactKey] = $entry->contactEmail;
}
$toEmail = (array_key_exists($toEmailId, $allAddresses))? $allAddresses[$toEmailId] : null;
return [
'toEmail' => ($toEmail ?: null),
'prependSubject' => '',
'prependSender' => 'From website:',
'allowAttachments' => false,
'successFlashMessage' => 'Thanks for your message'
];
}
On my contacts page that lists all the possible contacts, the submit to the contact form passes the id of the entry:
<input type="hidden" name="id" value="{{ entry.id }}">
In the contact form template I get that entry:
{% set entry = craft.entries.id(craft.app.request.getBodyParam('id')).one() %}
Which enables you to be able to show/confirm the contact name/details of who the form will send to and get access to the contactKey.
<p><strong>You are sending this message to:</strong><br>
{{ entry.contactName }}, {{ entry.contactPosition }}</strong></p>
The contact form template is based on the P&T example. With the addition of this line to allow "Dynamically adding email recipients", as detailed on the P&T example.
<input type="hidden" name="toEmail" value="{{ entry.contactKey }}">
I had problems updating the original method to work with Craft 3.7 and am grateful for the help of MoritzLost in this thread to get it working again.