Jump to content

Getting email from a processwire form (solved)


ryanC
 Share

Recommended Posts

Hi, I am testing my Processwire site locally through MAMP. I have created a form (outside of processwire) and managed to have the form send an email to myself. Now that I am trying to integrate that form into Processwire, the email is no longer being sent. I have done some searches, and see people are using wireMail, but I am not sure if that is what I need at this stage. 

The working code for the form I have is this:

    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if($email) {
        $headers .="\r\nReply-To: $email";
    }
    $headers = "From: myemail@xyz.com\r\n";
    $headers .= 'Content-Type: text/plain; charset=utf-8';
    if (isset($_POST['submit'])) {
    $to = 'myemail@xyz.com';
    $subject = 'Feedback from my site';
    $message = 'Name: ' . $_POST['name'] . "\r\n\r\n";
    $message .='Email: ' . $_POST['email'] . "\r\n\r\n"; 
    $message .='Comments: ' .$_POST['comments']. "\r\n\r\n";
    
    //custom
//    $message .='largestyle: ' .$_POST['largestyle']. "\r\n\r\n";
    
    $message .='large: ' .$_POST['large']. "\r\n\r\n";
    $message .='medium: ' .$_POST['medium']. "\r\n\r\n";
    $message .='small: ' .$_POST['small']. "\r\n\r\n";

    $success = mail($to, $subject, $message, $headers, '-fmyemail@xyz.com');
 }

So far, all I know is that adding the letter "f" to my email (last line of code) is the thing that's supposed to make the email work. If I were to add wireMail to this, where exactly would it go?  I added this:

<?php $mail = wireMail(); ?>

to the top of the document but that didn't do anything.  Any ideas?

Thanks!

Link to comment
Share on other sites

2 hours ago, ryanC said:

<?php $mail = wireMail(); ?>

You need to use that object – $mail – after you have created it. Like this:

https://processwire.com/talk/topic/5693-new-module-type-wiremail/

This topic might get you started:

https://processwire.com/talk/topic/8753-simple-wiremail-implementation-on-localhost/

But the easiest/fastest way to setup a contact/enquiry/feedback form is using Simple Contact Form module from @justb3a

  • Like 3
Link to comment
Share on other sites

4 hours ago, szabesz said:

You need to use that object – $mail – after you have created it. Like this:

Do you know where I might do this? I've been looking at these links, I am way over my head here. I'm good with HTML and CSS, and am learning the PHP stuff I can as I develop the site, but this is way beyond me right now. 

The form I'm making is very customized, with images, it's not just a contact form. I can't rebuild it from scratch--It does everything I need, I just need Processwire to treat email the way my local machine is treating email. 

As far as I know the code above is where the "chain" ends, where does the object "$mail" fit into the bigger picture? 

The php "mail" on the last line... 

 $success = mail($to, $subject, $message, $headers, '-fmyemail@xyz.com');

....isn't that the "mail" that

  "$mail = wireMail();"

is pointing to? I've already tried changing it to:

 $success = $mail($to, $subject, $message, $headers, '-fmyemail@xyz.com');

But that was just a guess.

Link to comment
Share on other sites

9 hours ago, ryanC said:

The php "mail" on the last line... 

 $success = mail($to, $subject, $message, $headers, '-fmyemail@xyz.com');

....isn't that the "mail" that

  "$mail = wireMail();"

is pointing to? I've already tried changing it to:

 $success = $mail($to, $subject, $message, $headers, '-fmyemail@xyz.com');

But that was just a guess.

PHP's mail() is "just" a simple function one can call.

However, WireMail is a class, which means one can use it to instantiate objects (ie. "create instances of it") which can be used to "manage" the action of sending emails. You can read a bit about OOP here, for example.

First of all $m = wireMail(); gets an instance of WireMail and stores a reference to it in $m.

$m is just a variable, it can be called "anything" (except for reserved words, of course) like $mail but do not confuse the function mail() with the variable $m

Just copy the complete examples provided in the docs or in Ryan's post and adjust it accordingly. For example:

$mail = wireMail();
$mail->to('user@hi.com')->from('ryan@runs.pw'); // all calls can be chained
$mail->subject('Mail Subject'); 
$mail->body('Mail Body');
$mail->bodyHTML('<html><body><h1>Mail Body</h1></body></html>'); 
$mail->send(); 

That is a simple example which should work.

  • Like 4
Link to comment
Share on other sites

Thanks for explaining that szabesz, much of that makes sense as it builds on what I've been doing with non-form pages in processwire. I'm sure part of it is this is my first tackling of HTML forms in general, so I'm adding an extra level of abstraction to something I don't fully understand in the first place. 

I understand that $variables point to something else, I get the concept of classes as that is similar to CSS, I see how wireMail and WireMail have different purposes, so I guess I'm half-way there. 

I'm going to start with a new basic test form and see if I can get some kind of functionality going. 

  • Like 2
Link to comment
Share on other sites

Ok... I am still not able to even start understanding this. I have read the links.... I can't get it. I am trying. Clearly knowing PHP is the answer, but I am not a programmer. 

 I have created a basic form page:

    <form id="simpleForm1" action="http://localhost:8888/sitename/form-response-1" method="post" target="_blank">
 
        <label for="name">Name:</label>
        <input type="text" name="name" id="name">
        
        <label for="email">Email:</label>
        <input type="email" name="email" id="email"><br /><br />
        
        <label for="comments">Comments:</label>
        <textarea name="comments" id="comments"></textarea>
     
    <div class="submission-test">
        <input type="submit" name="submit" value="Submit">
    </div>
    </form>

 

And here is the post page that the form goes to (I'll call it Code A)

<?php
    
    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if($email) {
        $headers .="\r\nReply-To: $email";
    }
    $headers = "From: myemail@xyz.com\r\n";
    $headers .= 'Content-Type: text/plain; charset=utf-8';
    if (isset($_POST['submit'])) {
    $to = 'myemail@xyz.com';
    $subject = 'Feedback from my site';
    $message = 'Name: ' . $_POST['name'] . "\r\n\r\n";
    $message .='Email: ' . $_POST['email'] . "\r\n\r\n"; 
    $message .='Comments: ' .$_POST['comments'];

    $success = mail($to, $subject, $message, $headers, '-fmyemail@xyz.com');
 }

?>

This is the new code I'm trying to work my head around (I'll call it Code B).

<?php $mail = wireMail(); ?>


 <?php
    $mail = wireMail();
    $mail->to('myemail@xyz.com')->from('myemail@xyz.com'); // all calls can be chained
    $mail->subject('Mail Subject'); 
    $mail->body('Mail Body');
    $mail->bodyHTML('<html><body><h1>Mail Body</h1></body></html>'); 
    $mail->submit(); 
?>

Does this new code replace the original code from Code A? Or maybe another way to ask... could this new wireMail code be worked into my HTML above?  

Alternately, I've seen people use something called Swiftmailer... would that be easier for me to implement? Maybe another third party service? 

I appreciate the help... I know these seem like really basic questions but I feel like someone in an algebra class who has the math skills of a third grader. You guys probably feel like I do when I try show my parents how to use their remote control. 

Link to comment
Share on other sites

I think you're nearly there. I'll have a stab at this and maybe, if you take code B, and add to it:

<?php
// wrap the whole thing in a condition that only runs
// if the form has actually been submitted
if ($input->post->submit) {
  
  // get the values submitted from the form via the 'name' attribute on each input field, 
  // pass them through sanitization (to remove any possible malicious code),
  // and save to variables
  $name = $sanitizer->text($input->post->name);
  $userEmail = $sanitizer->email($input->post->email);
  $comments = $sanitizer->text($input->post->comments);
  $subject = "Feedback from my site";
  $myEmail = "me@me.com";

  // construct the email body content that you'll receive
  $emailContent = "
      <html>
          <body>
              <p><b>Name:</b> {$name}</p>
              <p><b>Email:</b> {$userEmail}</p>
              <p><b>Comments:</b></p>
              <p>{$comments}</p>
          </body>
      </html>
      ";

  // create new wireMail object
  $mail = wireMail();

  $mail->to($myEmail)->from($userEmail);
  $mail->subject($subject); 
  $mail->bodyHTML($emailContent); 
  $mail->send(); 
}

?>

It would replace your Code A. I'm not as experienced as the other members here but I think something like this.

=EDIT=

You'll want some kind of validation though because this would run even if the fields weren't all filled out. This is what...

wireIncludeFile("./vendor/vlucas/valitron/src/Valitron/Validator.php");

$v = new \Valitron\Validator(array(
    "name" => $name,
    "email" => $email,
    "message" => $message
    )
);

$v->rule("required", ["name", "email", "message"]);
$v->rule("email", "email");

...from my original link does. Makes sure the required fields are not empty. Worry about that once the form works though ;)

Edited by SamC
Code correction
  • Like 3
Link to comment
Share on other sites

11 hours ago, ryanC said:

Does this new code replace the original code from Code A? Or maybe another way to ask... could this new wireMail code be worked into my HTML above?  

 

This should send the email:

<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if (isset($_POST['submit'])) {
     $to = 'myemail@xyz.com';
     $subject = 'Feedback from my site';
     $message = 'Name: ' . $_POST['name'] . "\r\n\r\n";
     $message .='Email: ' . $_POST['email'] . "\r\n\r\n";
     $message .='Comments: ' .$_POST['comments'];

    $mail = wireMail();
    $mail->to($to)->from('myemail@xyz.com'); // all calls can be chained
    $mail->subject($subject); 
    $mail->body($message);
    $mail->send(); 
}

 

  • Like 1
Link to comment
Share on other sites

Not getting anywhere yet, and these seem pretty thorough. 

When I was testing this out of my regular htdocs folder, I had to add the "-f" before my email address to get the email, something to do with validation. I have added that 'f' to your two examples just to see what would happen, no email yet.

Is it possible that  ProcessWire being installed locally (and not installed on an actual web server) have anything to do with it?

...also I have it set up like this: form itself is on one page which is based on my main template, and the form results page is based on an entirely different template. 

... this edit is a few hours later... from one of the threads above it mentions that the Wire Mail SMPT settings must be your email account and not your php ini settings. I entered my gmail SMTP hostname etc and it now says "SMTP settings appear to work correctly". I thought that would have been the culprit but still no email.

 

Link to comment
Share on other sites

12 hours ago, SamC said:

$mail->submit();

First of all, I copy/pasted your code and did not notice that you used submit instead of send. It is send. I corrected my post above.

I've been using MAMP Pro for a while – MAMP should work the same in this regard – and I can send emails even with PHP's built in mail() function, not just with SMTP. Meaning in my system both work. SMTP should work from your own local machine no matter what (provided it is configured properly, of course).

I use WireMailSmtp but Swift Mailer should work too.

Note that you can make sure the sending bit of the code works by using @adrian's Tracy Debugger. The Mail Interceptor Panel should be turned on temporarily only (Once or Sticky button), and by pasting the snippet into its Console and running it, it should show the message:

$mail = wireMail();
$mail->to('your@mail.com')->from('your@mail.com')->subject('test 1')->body('body 1')->send(); 

email-send-test.png.13d1730a830d2fded637557f162cbcc3.png

So first of all, make sure you can send emails. If Tracy can catch your mail, it means your code is ok, so you can move forward and set SMPT up if needed. If you get stuck with setting up the SMTP module, you can post questions in the appropriate forum threads.

Edited by szabesz
referencing Console was missing and typo
  • Like 4
Link to comment
Share on other sites

All three modules for ProcessWire capable of sending via SMTP are just piggy-back on WireMail (we have WireMailPHPMailer too)  meaning  we need to install and configure them but otherwise the code to send the actual email via WireMail is the same, but the module takes over to do the actual sending.

21 minutes ago, SamC said:

what extras does wiremailsmtp module bring compared to my approach above?

The approach itself should not matter in this regard.

I only use WireMailSmtp but probably the other two modules can also specify things like default Sender address and name, extra signatures, headers, valid recipients, etc...

Also, by sending via SMTP the email is less likely to land in a spam folder, and in some server environments it is not even possible to send via the default mail() function. Google offers 200 (as far as I can remember) SMTP messages a day, however the webserver itself should be able to send it via SMTP too. Google can be used if the local environment does not send it for some reason.

Edited by szabesz
typo
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Try enabling Mail Interceptor with the Sticky option. Probably I was wrong suggesting that the 'Once' option is ok in this case as it uses AJAX and the actual result should show up as a second row in Tracy's bar. First row displays "No emails sent" but the second row (titled AJAX) should be the intercepted email.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...