Sending mail attachment in NextJS+Axios+PHPMailer

Viewed 39

I'm struggling to send an email with attachment. The problem is only attachment, sending mail is OK.

My Form :

 <form onSubmit={handleSubmita}>
            <input
              type="text"
              placeholder="Name"
              id="app-user"
              name="app-user"
              required
              onChange={(e) => setForma({ ...forma, name: e.target.value })}
            />
            <input
              type="mail"
              placeholder="EMail (example@example.com)"
              id="app-mail"
              name="app-mail"
              pattern="^.+@.+\.[a-zA-Z]{2,63}$"
              required
              onChange={(e) => setForma({ ...forma, mail: e.target.value })}
            />
            <input
              type="text"
              placeholder="Mobile"
              id="app-mobile"
              name="app-mobile"
              required
              onChange={(e) => setForma({ ...forma, mobile: e.target.value })}
            />
            <input
              type="text"
              placeholder="department"
              id="app-department"
              name="app-department"
              required
              onChange={(e) => setForma({ ...forma, department: e.target.value })}
            />
            <input
              type="text"
              placeholder="Title"
              id="app-title"
              name="app-title"
              required
              onChange={(e) => setForma({ ...forma, title: e.target.value })}
            />
            <label
              htmlFor="app-file"
              className="w-full subpixel-antialiased text-sm flex items-center mt-1"
            ><AiOutlineFileText />Upload file
            </label>
            <input
              type="file"
              id="app-file"
              name="app-file"
              accept=".doc, .docx ,.pdf"                  
              required
              className='mt-1'
              onChange={(e) => setForma({ ...forma, file: e.target.files[0] })}
            />
            <div className="flex justify-evenly w-full bg-slate-200 my-3 xxs:flex-col p-2">
              <button
                className="flex justify-center items-center bg-red-100 mx-1 xxs:m-0"
                onClick={() => {
                  setForm(0)
                  setFull(false)
                }}
              >
                <AiOutlineDoubleLeft size={20} />{' '}
                <span className="ml-2">Back</span>
              </button>
              <button
                className="flex justify-center items-center bg-emerald-100 mx-1 xxs:m-0 xxs:mt-2"
                id="app-btn-submit"
                type="submit"
              >
                <AiOutlineSend size={20} />{' '}
                <span className="ml-2">Send!</span>
              </button>
            </div>
          </form>

As you can see I store form's data in a useState, it's like

const [forma, setForma] = useState({
name: '',
mail: '',
mobile:'',
department:"",
title:"",
file:""

})

When a user clicks the submit button, axios runs,

const handleSubmita = (e) => {
e.preventDefault()
console.log(forma)
setSpinner(true)

axios({
  method: 'post',
  url: process.env.NEXT_PUBLIC_URL_A, //URL comes from .env file
  headers: { 'content-type': 'application/json' },
  data: forma,
})
  .then((result) => {
    console.log(result.data)
    if (result.data == '200') {
      setSpinner(false)
      setResultqform(true)
    } else {
      setSpinner(false)
      setError(true)
    }
  })
  .catch((error) => console.log('error'))

}

PHP Side

<?php

  header('Access-Control-Allow-Origin: *');
  header('Access-Control-Allow-Headers: Content-Type');
  $rest_json = file_get_contents('php://input');
  $_POST = json_decode($rest_json, true);
  
  use PHPMailer\PHPMailer\PHPMailer;

  if (
      isset($_POST['name']) &&
      isset($_POST['mail']) &&
      isset($_POST['file']) &&
      isset($_POST['title']) &&
      isset($_POST['mobile']) &&
      isset($_POST['department'])
  ) {
var_dump($_POST);
$_POST['name'] = htmlentities($_POST['name']);
$_POST['mail'] = htmlentities($_POST['mail']);
$_POST['title'] = htmlentities($_POST['title']);
$_POST['mobile'] = htmlentities($_POST['mobile']);
move_uploaded_file( $_FILES[$_POST['file']]['tmp_name'],"tmp/".$_FILES[$_POST['file']]['name']);
require_once 'PHPMailer/PHPMailer.php';
require_once 'PHPMailer/SMTP.php';
require_once 'PHPMailer/Exception.php';

$mail = new PHPMailer();
date_default_timezone_set('Europe/London');
$now = date_create()->format('Y-m-d H:i:s');
try {
    $mail->isSMTP(); //Send using SMTP
    $mail->Host = $Host; //Set the SMTP server to send through
    $mail->SMTPAuth = true; //Enable SMTP authentication
    $mail->Username = $uname; //SMTP username
    $mail->Password = $pass; //SMTP password
    $mail->SMTPSecure = 'ssl'; //Enable implicit TLS encryption
    $mail->Port = $port;
    $mail->CharSet = 'UTF-8';

    $mail->setFrom($mailer, 'Mailer');
    $mail->addAddress($recipent, $recipent_info); //Add a recipient
    $mail->addReplyTo($_POST['mail'], $_POST['name']);

    $file_tmp = $_FILES[$_POST[$_POST['file']]]['tmp_name'];
    $file_name = $_FILES[$_POST[$_POST['file']]]['name'];
    $mail->AddAttachment($file_tmp, $file_name);

    //Content
    $mail->isHTML(true); //Set email format to HTML
    $mail->Subject = 'Test';
    $mail->Body =
        '<b>' .
        $_POST['name'] .
        '</b> =name<br/><br/>';
    $mail->Body .=
        '<b>department:</b> ' .
        $_POST['department'] .
        '<br/><br/>';
    $mail->Body .=
        '<b>title:</b> ' . $_POST['title'] . '<br/><br/>';
    $mail->Body .= '<b>Mobile:</b> ' . $_POST['mobile'] . '<br/><br/>';
    $mail->Body .= '<b>Mail:</b> ' . $_POST['mail'] . '<br/><br/>';
    $mail->Body .= '<b>Time: </b>' . $now;

    //$mail->send();

    if ($mail->send()) {
        echo '200';
        echo $_POST;
    } else {
        echo $mail->ErrorInfo;
    }
} catch (Exception $e) {
    echo "Error! Mailer Error: {$mail->ErrorInfo}";
}
  }

  ?>

Axios send file's data but PHP doesn't get it, I don't understand why. Here is screenshot, (mail is being sent without attachment).

enter image description here

It's the first time, I am trying to send an attachment. if I'm doing it the wrong way, pls advise.

1 Answers

Finally I solved the problem. I am writing the solution maybe someone has similar problems.

1- In axios, I changed the code "headers: { 'content-type': 'application/json' }," with "headers: { 'Content-Type': 'multipart/form-data' },". That makes sense since I also want to send file infos.

2- In PHP, I learnt that files can be sent through POST method but they need to handle by using FILES method. So my code became

///////////Strings
$name = htmlspecialchars($_POST['name']);
$mail_sender = htmlspecialchars($_POST['mail']);
$title = htmlspecialchars($_POST['title']);
$department = htmlspecialchars($_POST['department']);
$mobile = htmlspecialchars($_POST['mobile']);
$status = htmlspecialchars($_POST['status']);

///////////Attachment Info
$file_name=$_FILES['file']['name'];
$file_tmp=$_FILES['file']['tmp_name'];

In PHP, I add these data to send attacchment.

$mail->AddAttachment($file_tmp, $file_name);

Also, I removed the move_uploaded_file line since I don't need to store files, just want to send it through an email.

And that's it, it works perfectly now.

Related