How to handle wordpress forms via php?

33 Views Asked by At

I have a contact form on my wordpress website and I am trying to send an email accordingly. However neither an email nor a response is being send to the client. Even without the condition in the beginning it's not working. I don't get any server logs regarding this issue.

What am I doing wrong?

add_action('wp_ajax_nopriv_mail_before_submit', 'mail_before_submit');
add_action('wp_ajax_mail_before_submit', 'mail_before_submit');
function mail_before_submit() {
    $jsonRequest = json_decode(file_get_contents('php://input'), true);
    if (strcmp($jsonRequest['action'], 'contact_form') !== 0) {
        echo 'failure';
        exit(1);
    };

    $sendMail = wp_mail(
        get_option('admin_email'),
        sprintf('Kontaktformular von %1$s', $jsonRequest['name']),
        sprintf(
            'Name: %1$s
Email: %2$s
Telefonnummer: %3$s
Nachricht: %4$s
JSON: %5$s',
            $jsonRequest['name'],
            $jsonRequest['email'],
            $jsonRequest['phone'],
            $jsonRequest['message'],
            json_encode($jsonRequest),
        ),
        sprintf('From: %1$s <"%2$s">', $jsonRequest['name'], $jsonRequest['email']),
    );

    if ($sendMail) {
        echo 'success';
        exit();
    }

    echo 'failure';

    exit();
}

Best regards

EDIT1:

I used https://ddev.readthedocs.io/en/latest/users/debugging-profiling/step-debugging/#visual-studio-code-vs-code-debugging-setup for debugging and found, that the headers argument of the wp_mail funtion is incorrect, so I replaced it with sprintf('From: %1$s', $jsonRequest['email']),.

Now I am receiving the mail, however no response to the client is being sent. Why is that?

EDIT2:

The code above works with the mentioned change in EDIT2, what I didn't know is, that the response in the browsers network tab will be empty, until in JavaScript something like await response.text() has been called.

1

There are 1 best solutions below

0
pgalle On BEST ANSWER

The whole working PHP part looks like this:

add_action('wp_ajax_nopriv_mail_before_submit', 'mail_before_submit');
add_action('wp_ajax_mail_before_submit', 'mail_before_submit');
function mail_before_submit() {
    $jsonRequest = json_decode(file_get_contents('php://input'), true);
    if (strcmp($jsonRequest['action'], 'contact_form') !== 0) {
        echo 'failure';
        exit(1);
    };

    $sendMail = wp_mail(
        get_option('admin_email'),
        sprintf('Kontaktformular von %1$s', $jsonRequest['name']),
        sprintf(
            'Name: %1$s
Email: %2$s
Telefonnummer: %3$s
Nachricht: %4$s',
            $jsonRequest['name'],
            $jsonRequest['email'],
            $jsonRequest['phone'],
            $jsonRequest['message'],
            // json_encode($jsonRequest),
        ),
        sprintf('From: %1$s', $jsonRequest['email']),
    );

    if ($sendMail) {
        echo 'success';
        exit();
    }

    echo 'failure';

    exit();
}

On the JavaScript side it's important to call await response.text(), otherwise the response won't be visible in the browsers network tab.

window.addEventListener("load", () => {
  /**
   * @type Array<HTMLFormElement>
   */
  const forms = Array.from(
    document.querySelectorAll(".contact-form")
  );

  forms.forEach((form) => {
    form.addEventListener("submit", async (e) => {
      e.preventDefault();

      const response = await fetch(
        "/wp-admin/admin-ajax.php?action=mail_before_submit",
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            action: "contact_form",
            ...Object.fromEntries(new FormData(form)),
          }),
        }
      );

      console.log({ response });
      if (!response.ok) {
        console.error("ERROR");

        return;
      }

      if ((await response.text()) === "success") {
        form.classList.add("success");
      }
    });
  });
});