Sending emails via contact form

Cupara
Member | 90
+
0
-

I'm trying to get my contact form to send an email upon clicking submit but I get an error that it's trying to access a protected function so I change it to public function all it does is refresh the page.

Here is my ContactPresenter.php

<?php

declare(strict_types=1);

namespace App\Presenters;

use Nette;
use Nette\Application\UI\Form;
use Nette\Mail\Message;


final class ContactPresenter extends Nette\Application\UI\Presenter
{
    public function __construct(
        private Nette\Database\Explorer $database,
    ) {
    }

    public function renderShow(): void
    {
        $this->template->contact = $this->createComponentContactForm();
    }

    protected function createComponentContactForm(): Form
    {
        $form = new Form;
        $form->addText('name', 'Your name:')
            ->setRequired();
        $form->addEmail('email', 'Your e-mail:')
            ->setRequired();
        $form->addText('subject', 'Subject:')
            ->setRequired();
        $form->addTextArea('message', 'Message:')
            ->setRequired();
        $form->addSubmit('send', 'Send');
        $form->onSuccess[] = [$this, 'contactFormSucceeded'];
        return $form;
    }

    protected function contactFormSucceeded(\stdClass $data): void
    {
        $mail = new Message;

        $mail->setFrom($data->email)
            ->addTo('cupara@serenitydev.xyz')
            ->setSubject($data->subject)
            ->setBody($data->message);
    }

}

Here is my default.latte for the contact form

{block content}
<style>
    #container {
        width: 1000px;
        margin: 20px auto;
    }
    .ck-editor__editable[role="textbox"] {
        /* editing area */
        min-height: 200px;
    }
    .ck-content .image {
        /* block images */
        max-width: 80%;
        margin: 20px auto;
    }
    .ck-editor__editable_inline:not(.ck-comment__input *) {
        height: 300px !important;
        overflow-y: auto !important;
    }
</style>
<div id="editor">
    <div class="form" style="width: 100%">
        {form contactForm}
            <div class="form-group">
                <label n:name="name" />
                <input n:name="name" class="form-control" />
            </div>
            <div>&nbsp;</div>
            <div class="form-group">
                <label n:name="email" />
                <input n:name="email" class="form-control" />
            </div>
            <div>&nbsp;</div>
            <div class="form-group">
                <label n:name="subject" />
                <input n:name="subject" class="form-control" />
            </div>
            <div>&nbsp;</div>
            <div class="form-group">
                <label n:name="message" />
                <textarea n:name="message" id="data-editor" class="form-control" rows="10"></textarea>
            </div>
            <div>&nbsp;</div>
            <div class="form-group">
                <input name="submit" type="submit" class="btn btn-success">
            </div>
        {/form}
    </div>
</div>
<div>&nbsp;</div>
{/block}

Last edited by Cupara (2024-01-16 12:21)

MajklNajt
Member | 471
+
+1
-

change

<input name="submit" type="submit" class="btn btn-success">

to

<input n:name="send" class="btn btn-success">
Kamil Valenta
Member | 762
+
+3
-

Cupara wrote:

        $mail = new Message;

        $mail->setFrom($data->email)
            ->addTo('cupara@serenitydev.xyz')
            ->setSubject($data->subject)
            ->setBody($data->message);

$mail->send();
?

jiri.pudil
Nette Blogger | 1028
+
+4
-

Or rather $this->mailer->send($mail), with mailer injected via the constructor:

    public function __construct(
        private Nette\Database\Explorer $database,
        private Nette\Mail\Mailer $mailer,
    ) {
    }

see https://doc.nette.org/en/mail#…


I get an error that it's trying to access a protected function so I change it to public function

In PHP >= 8.1 you can use the first-class callable syntax:

$form->onSuccess[] = $this->contactFormSucceeded(...);

This is a shorthand for Closure::fromCallable which encloses the callback with current scope. As a result, the contactFormSucceeded can (and should) be made protected or even private.

Cupara
Member | 90
+
0
-

Thank you all for the feedback. I have updated my code but I still get this error from contactFormSucceeded being a protected function:
https://imgur.com/ksObI5E

If I change it to private function I get the same error but for it being private.

Last edited by Cupara (2024-01-17 22:48)

Infanticide0
Member | 59
+
0
-

What do you use?

$form->onSuccess[] = $this->contactFormSucceeded(...);

or

$form->onSuccess[] = [$this, "contactFormSucceeded"];
Cupara
Member | 90
+
0
-

I forgot to change it to $this->contactFormSucceeded(...);

I changed it to that and all is good. My website is now ready to be launched just one last thing. How do I disable the debug bar for a production site @Infanticide0 ?

Infanticide0
Member | 59
+
0
-

@Cupara
Debug mode is not enabled when localhost is not detected. If you manually (force) enabled it in app/Bootstrap.php, disable it by

$configurator->setDebugMode(false);

or use "cookie@1.2.3.4" string|string[] to enable debug mode only for developer.

see docs
https://doc.nette.org/…on/bootstrap#…

Last edited by Infanticide0 (2024-01-17 23:27)

Cupara
Member | 90
+
0
-

Ok thanks.