So first of all there is a BUG in Blocs that makes the Form Handler JS fail in a 404.
This, on WP Exported Theme. Not sure the same happens in other exports.
It fails into 404 because it calls ./js/path-to-file
instead of <?php echo get_template_directory_uri(); ?>/js/path-to-file
.
So that needs to be fixed or a Form will never work in a WP Exported Theme of blocs when it is self-hosted.
Will report that to Norm later.
Once that is fixed (or adjusted manually in a theme) we can send easily email using the self-hosted option.
No further ado, that will work immediately on any WP Ready Server, as they all will have to enable mail(), no matter what.
Now for the challenge of SMTP, yes on WP We would just install a plugin, and this is a little more complex than I initially thought when done in pure PHP. Not to speak about static HTML sites, I would not know (when not using WP/PHP with server side logic) how exactly to add and require files in such sites, but I guess it could be done with just plain PHP as well.
That said, not using a SMTP plugin but wanting to add our own SMTP solution, is not that easy, but possible.
- When creating the Blocs Form, we need to choose “Custom”
- It then asks us to add an “Action”. This, in PHP Forms generally is the path to the file which will hold the code with our Custom Mail Method. To make it simpler, when creating the form in Blocs, simply add
placeholder
in that field.
- Then export the theme or site and find the file where the Blocs form was added. Open it in a code editor.
- Locate the
action="placeholder"
part and replace that with the path to the PHP File that will hold our Custom Mail Method. In my case, I put that file in the Theme subfolder, so the path is:
action="<?php echo get_template_directory_uri(); ?>/includes/custom-form-function.php"
. In other cases that might be:
action="/path/to/site/the-site.com/public_html/whatever-site-folder/perhaps-subfolder/custom-form-function.php"
. Important is that custom-form-function.php
path is called. custom-form-function.php
is the file where we will put our Custom Mail Method.
- Now open (or create if you did not already) the
custom-form-function.php
file which is where we will add our Custom Mail Method. Here it will depend heavily what service/API you use, which will determine what code we write.
Of course, in this file you could just use a plain old simple mail()
method, but remember we wanted to use SMTP
So we need to find a SMTP PHP API. I used SendPulse.
Every API is based on some larger code, in the case of SendPulse, you need to install all the files (following the same structure, name and folders) from here somewhere on your server.
I added them to my theme, under the path-to-theme/sendpulse-rest-api-php/src
folder. You cold add them anywhere you like, important is that later in our custom-form-function.php
file we specify the path properly.
Done that, we can implement their API in our custom-form-function.php
file.
We can start with this example (see Usage and do not use composer, instead require
each file separately as in the comments shown on that example code)
The code shown in that example would be put into our custom-form-function.php
file.
Since we call that file with the action from our Bloc Form, it will execute that code in the file once it is called.
A mail would be sent using the example setup of the SendPulse code.
We want to modify this and include the data that was inserted in the Bloc Form instead.
To get the actual contents from the Blocs Form that was submitted, we would have to listen to $_POST
(or $_GET
if we chose GET
in the blocs form settings…)
This will give us an Array of the form inputs submitted when completing and submitting the Blocs Form.
It might look like this:
["name_40559"]=> string(8) "John Doe"
["email_40559"]=> string(14) "some@email.com"
["message_40559"]=> string(21) "some fancy message..."
["optin_40559"]=> string(2) "on"
In short, those are all fields I included in the form, and the default Blocs Checkbox “Opt In” that is added when creating a Form in Blocs.
The left side shows the keys (read: name or ID), the right side the values of the fields.
This is what the user inserted in the Blocs Form when he/she pressed “submit”.
Using that, we can then compose our email, and send it away using the SendPulse PHP API.
So instead of the hardcoded strings as seen in SendPulse’s API Example we would insert our PHP variables built with the $_POST
data.
Without any further sanitisation, fancytinisation and what not (sanitisation is 100%, absolutely mandatory but I omitted it because it would go out of scope and is also very different in WP than it is in raw PHP), the completed Custom Mail Method in our custom-form-function.php
file looks like this:
$path_to_api = '/path/to/site/folder/where/api/is/located';
require($path_to_api.'/sendpulse-rest-api-php/src/ApiInterface.php');
require($path_to_api.'/sendpulse-rest-api-php/src/ApiClient.php');
require($path_to_api.'/sendpulse-rest-api-php/src/Storage/TokenStorageInterface.php');
require($path_to_api.'/sendpulse-rest-api-php/src/Storage/FileStorage.php');
require($path_to_api.'/sendpulse-rest-api-php/src/Storage/SessionStorage.php');
require($path_to_api.'/sendpulse-rest-api-php/src/Storage/MemcachedStorage.php');
require($path_to_api.'/sendpulse-rest-api-php/src/Storage/MemcacheStorage.php');
use Sendpulse\RestApi\ApiClient;
use Sendpulse\RestApi\Storage\FileStorage;
// API credentials from https://login.sendpulse.com/settings/#api
define('API_USER_ID', '');//add api keys
define('API_SECRET', '');//add api keys
$SPApiClient = new ApiClient(API_USER_ID, API_SECRET, new FileStorage());
/*
* Example: Send name, email and message from Blocs Form
*/
$email = array(
'text' => $_POST['message_40559'],//This is the name of the input field in Form
'subject' => 'Attention, new mail from your site.',//Simple string
'from' => array(
'name' => $_POST['name_40559'],//This is the name of the input field in Form
'email' => $_POST['email_40559'],//This is the name of the input field in Form
),
'to' => array(
array(
'email' => 'hello@oursite.com',//Simple hardcoded receiver, which is me in this case.
),
),
);
//error_log( print_r( $SPApiClient->smtpSendMail($email), true) );//Because I am dumb and often make errors ;)
$SPApiClient->smtpSendMail($email);//instantiate smtpSendMail() to send email.
This is very rough, unsanitised example. The very least it would need some sanitisation on the $_POST data so no malicious crap can be submitted by scriptkiddies.
Using this method, you cannot submit the form with AJAX as Blocs does natively, unless you implement additional logic to do so. There will be also no validation and sanitisation as done by blocs when using the self-hosted version. No redirection logic and success message or failure message is implemented either in this example. This would all require additional work, either tailored to WP, or other types of Custom CMS/Sites/Business logic.
Finally - SMTPs (at least the one I signed up for) is not immediately 100% active, since they manually review each and every user and it takes up to 24hrs to do that.
So, it means you need to wait 24 hours after subscribing to actually use this code successfully.
I am NOT sure this helps anyone lol, but it certainly helped me and was a cool exercise to do.
Now I guess I’ll go and deploy a WP Plugin doing just that a bit easier jajaja.
@Mattheus - I guess you will be quicker by simply asking your host to enable mail() or perhaps you have a choice to move over to WP, where you could use a Plugin for all this.
And sorry if the expectations where made to have a simple way, I couldn’t find any simple(r) way than above, when we go full custom-crafted thingy…
The solution I mentioned in an earlier comment seems to work with Google SMTP but that requires Google Workspace-Accoutn, which I have no access to. And, it may not work because PHP itself does not actually allow for authentication of external SMTP (and that is why Google’s solution might work, as they offer a non-authenticated solution). Also, I think the whole points of SMTP is to make things safe and secure, so a unauthenticated SMTP to me sounds like no solution.
Perhaps someone else knows more/better ways to do this in pure PHP, I will be eager to learn to it