PHP Mailer in Kirby

Hi,

I’m trying to setup PHP Formmailer to work with my contakt form. This is the code of the kontakt.php template which lives inside the templates folder:

<?php snippet('header') ?>

    <div class="form-wrapper">
      <h2>Wir freuen uns auf Ihren Kontakt</h2>
        <form class="new-form__form" action="mail.php" method="POST">
          <div class="new-form__inputs-wrapper">
          <div class="new-form__input-block">

          <!-- <input type="hidden" name="admin_email[]" value="hello@myhost.com">
          <input type="hidden" name="form_subject"
          value="Contact form from hello@myhost.com(footer)"> -->

    <label for="name">Ihr Name<span class="asterisk"> &#42;</span></label>
    <input type="text" id="name" name="user_name" required />
  </div>
    <div class="new-form__input-block">
      <label for="email">Ihre E-Mail-Adresse<span class="asterisk"> &#42;</span></label>
      <input type="email" id="email" name="user_email" required />
    </div>
  <div class="new-form__input-block">
    <label for="tel">Ihre Telefonnummer<span class="asterisk"> &#42;</span></label>
     <input type="tel" id="tel" name="user_phone" required />
    </div>
  </div>
<div class="new-form__textarea">
  <label for="message">Ihre Nachricht</label>
  <textarea id="message" name="message" required placeholder="Bitte schreiben Sie Ihren Text hier"></textarea>
  </div>
<div>
  <p><input type="checkbox" required id="subscribe" name="Datenschutz" value="Einverstanden">
  <label for="subscribe"><span class="datenschutz">Ich bin mit der Datenschutzerklärung einverstanden.</span></label></p>
</div>
  <button type="submit" class="new-form__submit">Senden</button>
</form>
</div>
    
<?php snippet('footer') ?>

Now, I created a mail.php file and stored it in the Kirby main folder (attached is a screenshot of the tree structure). This is the code inside the mail.php:

<?php
require_once('phpmailer/PHPMailerAutoload.php');
$mail = new PHPMailer;
$mail->CharSet = 'utf-8';$name = $_POST['user_name'];
$phone = $_POST['user_phone'];
$email = $_POST['user_email'];
$message = $_POST['message'];
$agreeRules = $_POST['Datenschutz'];
if($agreeRules = "Einverstanden"){
$agreeMessage = "Ich bin mit der Datenschutzerklärung einverstanden";
}else{
    $agreeMessage = "false";
}
$mail->SMTPDebug = 3;                               // Enable verbose debug output

$mail->isSMTP();                                      // Set mailer to use SMTP
$mail->Host = 'Z000000.worldservy.com';  																							// Specify main and backup SMTP servers
$mail->SMTPAuth = true;                               // Enable SMTP authentication
$mail->Username = 'hello@myhost.com'; // 
$mail->Password = 'MyStrongPassword21'; //
$mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to /
$mail->setFrom('hello@myhost.com'); 
$mail->addAddress('hello@myhost.com');
//$mail->addAddress('ellen@example.com');               // Name is optional
//$mail->addReplyTo('info@example.com', 'Information');
//$mail->addCC('cc@example.com');
//$mail->addBCC('bcc@example.com');
//$mail->addAttachment('/var/tmp/file.tar.gz');         // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg');    // Optional name
$mail->isHTML(true);                                  // Set email format to HTML

$mail->Subject = 'Contact form footer (hello@myhost.com)';
$mail->Body    = 'Name: ' .$name . ' <br> '.'Phone: ' .$phone. '<br>Email: ' .$email.'<br>'.'Message: '.$message.'<br>'.'Datenschutzerklärung: '.$agreeMessage;
$mail->AltBody = '';

if(!$mail->send()) {
    echo 'Error'.$mail->ErrorInfo;
} else {
    header('location: vielen-dank.html');
}
?>

When I fill in the contact form fields and click the submit button, the following message shows in the browser: This page isn’t working right now myhost.com can’t currently handle this request. HTTP ERROR 500. Grateful for your support.

screenshot

Thanks for the link. Is it possible for me to name the template kontakt.php instead of contact.php?

Thanks. I followed the link you provided and did the following:

  1. I created a kontakt.php file and saved it inside the templates folder. The code looks as follows:
<?php snippet('header') ?>

      <?php if($success): ?>
        <div class="alert success">
          <p><?= $success ?></p>
        </div>
        <?php else: ?>
        <?php if (isset($alert['error'])): ?>
            <div><?= $alert['error'] ?></div>
        <?php endif ?>
    <div class="form-wrapper">
      <h2>Wir freuen uns auf Ihren Kontakt</h2>
        <form method="post" action="<?= $page->url() ?>">
        <div class="honeypot">
          <div class="new-form__inputs-wrapper">
          <div class="new-form__input-block">
    <label for="name">Ihr Name<span class="asterisk"> &#42;</span></label>
    <input type="text" id="name" name="user_name" required />
    <?= isset($alert['name']) ? '<span class="alert error">' . esc($alert['name']) . '</span>' : '' ?>
  </div>
    <div class="new-form__input-block">
      <label for="email">Ihre E-Mail-Adresse<span class="asterisk"> &#42;</span></label>
      <input type="email" id="email" name="user_email" required />
      <?= isset($alert['email']) ? '<span class="alert error">' . esc($alert['email']) . '</span>' : '' ?>
    </div>
  <div class="new-form__input-block">
    <label for="tel">Ihre Telefonnummer<span class="asterisk"> &#42;</span></label>
     <input type="tel" id="tel" name="user_phone" required />
     <?= isset($alert['tel']) ? '<span class="alert error">' . esc($alert['tel']) . '</span>' : '' ?>
    </div>
  </div>
<div class="new-form__textarea">
  <label for="message">Ihre Nachricht</label>
  <textarea id="message" name="message" required placeholder="Bitte schreiben Sie Ihren Text hier">
    <?= esc($data['text'] ?? '') ?>
  </textarea>
  <?= isset($alert['textarea']) ? '<span class="alert error">' . esc($alert['textarea']) . '</span>' : '' ?>
  </div>
<div>
  <p><input type="checkbox" required id="subscribe" name="Datenschutz" value="Einverstanden">
  <label for="subscribe"><span class="datenschutz">Ich bin mit der Datenschutzerklärung einverstanden.</span></label></p>
</div>
  <button type="submit" name="submit" value="submit" class="new-form__submit">Senden</button>  
</form>
<?php endif ?>
</div>
    
<?php snippet('footer') ?>
  1. I created a 3_kontakt folder inside the content folder. Inside the 3_kontakt folder I created a konakt.txt file and placed the following:

Titel: kontakt


zeiten: Montag-Freitag: 8:15-16:00 Uhr Freitag: 08:15-13:06


  1. Inside the controllers folder, I created a a kontakt.php file and placed the following:
<?php
return function($kirby, $pages, $page) {

    $alert = null;

    if($kirby->request()->is('POST') && get('submit')) {

        // check the honeypot
        if(empty(get('website')) === false) {
            go($page->url());
            exit;
        }

        $data = [
            'name'  => get('name'),
            'email' => get('email'),
           'tel' => get('tel'),
            'text'  => get('text')
        ];

        $rules = [
            'name'  => ['required', 'minLength' => 3],
            'email' => ['required', 'email'],
          'tel' => ['required', 'tel'],
            'text'  => ['required', 'minLength' => 3, 'maxLength' => 3000],
        ];

        $messages = [
            'name'  => 'Please enter a valid name',
            'email' => 'Please enter a valid email address',
         'tel' => 'Please enter a valid phone number',
            'text'  => 'Please enter a text between 3 and 3000 characters'
        ];

        // some of the data is invalid
        if($invalid = invalid($data, $rules, $messages)) {
            $alert = $invalid;

            // the data is fine, let's send the email
        } else {
            try {
                $kirby->email([
                    'template' => 'email',
                    'from'     => 'hello@mydomainname.com',
                    'replyTo'  => $data['email'],
                    'to'       => 'hello@mydomainname.com',
                    'subject'  => esc($data['name']) . ' sent you a message from your contact form',
                    'data'     => [
                        'text'   => esc($data['text']),
                        'sender' => esc($data['name'])
                    ]
                ]);

            } catch (Exception $error) {
                if(option('debug')):
                    $alert['error'] = 'The form could not be sent: <strong>' . $error->getMessage() . '</strong>';
                else:
                    $alert['error'] = 'The form could not be sent!';
                endif;
            }

            // no exception occurred, let's send a success message
            if (empty($alert) === true) {
                $success = 'Your message has been sent, thank you. We will get back to you soon!';
                $data = [];
            }
        }
    }

    return [
        'alert'   => $alert,
        'data'    => $data ?? false,
        'success' => $success ?? false
    ];
};

Having uploaded the folders and files, I visited the kontakt page and the debugger returned a Undefined variable $success

I added this code and the debugger is no longer throwing an error but the form itself is not sending data:

<?php
    $success = false;
// Rest of your code...
?>

Grateful for your support.

Double-check your filenames, since success is returned from the controller, it cannot be undefined in the template.

Sorry, but I don’t know how to define it in the template :expressionless:

You don’t define it in the template, it is passed from the controller to the template in the return array. Therefore, it is not undefined. If it is undefined, then you have a problem probably in your filenames.

1 Like

I’ve kontakt.php in the templates folder and kontakt.php in the controllers folder.

In the kontakt.php which lives inside the controllers folders, I changed the template to ‘kontakt’ but it is still not sending any input via email. This is the change I made:

            // the data is fine, let's send the email
        } else {
            try {
                $kirby->kontakt([
                    'template' => 'kontakt',
                    'from'     => 'hello@myemail.com',
                    'replyTo'  => $data['hello@myemail.com'],
                    'to'       => '',
                    'subject'  => esc($data['name']) . ' sent you a message from your contact form',
                    'data'     => [
                        'text'   => esc($data['text']),
                        'sender' => esc($data['name'])
                    ]
                ]);

This form cannot possibly work because your field names (user_email etc) and what you try to fetch in the controller (get(‘email’)) doesn’t match.

You have to make sure to either copy a cookbook recipe to the T, or make sure you apply your changes in all places.

Hi, Thanks for pointing me in the right direction. In MS Edge I received this message (Firefox did not display it): “The form could not be sent: The email template “kontakt” cannot be found” after making the following changes:

<?php
return function($kirby, $pages, $page) {

    $alert = null;

    if($kirby->request()->is('POST') && get('submit')) {

        // check the honeypot
        if(empty(get('website')) === false) {
            go($page->url());
            exit;
        }

        $data = [
            'name'  => get('name'),
            'email' => get('email'),
            'tel' => get('tel'),
            'text'  => get('text')
        ];

        $rules = [
            'name'  => ['required', 'minLength' => 3],
            'email' => ['required', 'email'],
            'text'  => ['required', 'minLength' => 3, 'maxLength' => 3000],
        ];

        $messages = [
            'name'  => 'Please enter a valid name',
            'email' => 'Please enter a valid email address',
            'tel' => 'Please enter a valid phone number',
            'text'  => 'Bitte schreiben Sie Ihren Text hier'
        ];

        // some of the data is invalid
        if($invalid = invalid($data, $rules, $messages)) {
            $alert = $invalid;

            // the data is fine, let's send the email
        } else {
            try {
                $kirby->email([
                    'template' => 'kontakt',
                    'from'     => 'myname@gmail.com',
                    'replyTo'  => $data['email'],
                    'to'       => 'myname@gmail.com',
                    'subject'  => esc($data['name']) . ' sent you a message from your contact form',
                    'data'     => [
                        'text'   => esc($data['text']),
                        'sender' => esc($data['name'])
                    ]
                ]);

            } catch (Exception $error) {
                if(option('debug')):
                    $alert['error'] = 'The form could not be sent: <strong>' . $error->getMessage() . '</strong>';
                else:
                    $alert['error'] = 'The form could not be sent!';
                endif;
            }

            // no exception occurred, let's send a success message
            if (empty($alert) === true) {
                $success = 'vielen-dank.html';
                $data = [];
            }
        }
    }

    return [
        'alert'   => $alert,
        'data'    => $data ?? false,
        'success' => $success ?? false
    ];
};
  <?php if($success): ?>
    <div class="alert success">
    <p><?php go($success); ?></p>
  </div>
  <?php else: ?>
  <?php if (isset($alert['error'])): ?>
  <div><?= $alert['error'] ?></div>
  <?php endif ?>

  <div class="form-wrapper">
  <h2>Wir freuen uns auf Ihren Kontakt</h2>
    <form method="post" action="<?= $page->url() ?>">
    <div class="honeypot">
  
  <div class="new-form__inputs-wrapper">
    <div class="new-form__input-block">
    <label for="name">Ihr Name<span class="asterisk"> &#42;</span></label>
    <input type="text" id="name" name="name" required />
    <?= isset($alert['name']) ? '<span class="alert error">' . esc($alert['name']) . '</span>' : '' ?>
  </div>
    
  <div class="new-form__input-block">
      <label for="email">Ihre E-Mail-Adresse<span class="asterisk"> &#42;</span></label>
      <input type="email" id="email" name="email" required />
      <?= isset($alert['email']) ? '<span class="alert error">' . esc($alert['email']) . '</span>' : '' ?>
    </div>
  
  <div class="new-form__input-block">
    <label for="tel">Ihre Telefonnummer<span class="asterisk"> &#42;</span></label>
     <input type="tel" id="tel" name="tel" required />
     <?= isset($alert['tel']) ? '<span class="alert error">' . esc($alert['tel']) . '</span>' : '' ?>
    </div>
  </div>

  <div class="new-form__textarea">
  <label for="message">Ihre Nachricht</label>
 <textarea id="message" name="text" required placeholder="Bitte schreiben Sie Ihren Text hier"></textarea>
  </div>

<div>
  <p><input type="checkbox" required id="subscribe" name="Datenschutz" value="Einverstanden">
  <label for="subscribe"><span class="datenschutz">Ich bin mit der Datenschutzerklärung einverstanden.</span></label></p>
</div>

  <button type="submit" name="submit" value="submit" class="new-form__submit">Senden</button>  
</form>
<?php endif ?>
</div>
</div>

The kontakt.php template is inside the templates folder and the kontakt.php is inside the controllers folder. I’ve double checked.

Do I need to enter any credentials such as Email settings, etc. to make it work?

All steps necessary for sending email from a contact form are here in these two documents:

You are using an email template kontakt, does this exist in /site/templates/emails?

I repeat what I said before: If you deviate from the documentation, like use other filenames etc, you have to make sure to make these changes everywhere.

Maybe start with implementing it exactly as described, until you understand how it works.

Hi Ms. Broda,

I followed the instructions to the point and it did work- I filled the contact form and I received a message to my email. However, when I changed the names of the files to kontakt instead of contact, I received the following message when I clicked on the submit button: “The form could not be sent: Undefined variable $name”

I’m trying to understand the logic as a learner as to why this is happening and need guidance.

In the cookbook recipe, we don’t use a variable called $name anywhere, so you must have introduced this somewhere.

I did not introduce it in the files that pertain to the contact form.

I’m pretty sure you did more than just rename the files.