Skip to content
Advertisement

How to convert an image from input to json, send it in fetch to php and then send it on server via PHPMailer?

I’m not very good in PHP and all server stuff, so I would appreciate any answers and advice.

I need to send JSON data and an image in one fetch to php script.

Following this question How can I serialize an input File object to JSON?, I made object from image, put it in fetch and tried to send this object in PHPMailer as an attachment, but I’ve got this error:

[Sun Jan 24 15:07:52 2021] 127.0.0.1:59260 [500]: POST /dist/php/mail.php - Uncaught Error: Object of class stdClass could not be converted to string in /home/joe/Documents/vscode-projects/html-projects/swipeskins/dist/vendor/phpmailer/phpmailer/src/PHPMailer.php:3005

So, my JavaScript code:

 // firstly, declaration of variables
let files, 
    fileObject,
    newObject,
    myArray = [];
// when user uploads image with input, code makes new src for <img> tag with this image
form.onchange = (event) => {
 image.src = URL.createObjectURL(event.target.files[0]);
    
 image.onload = () => {
// on load of image I give new values to variables, and make an object with info from an image
 files = document.querySelector('[type=file]').files;
 fileObject = files[0];
 newObject  = {
  'lastModified'     : fileObject.lastModified,
  'lastModifiedDate' : fileObject.lastModifiedDate,
  'name'             : fileObject.name,
  'size'             : fileObject.size,
  'type'             : fileObject.type
    };  
   }
  }
// And here's the fetch :)
  fetch(`${server}/dist/php/mail.php`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      'preferences': purchase, // this is usual object 
      'jsonObject': newObject, // and this is an image object
    })
  });

And here’s the mail.php code:

<?php

use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerSMTP;
use PHPMailerPHPMailerException;

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: *');
header('Access-Control-Allow-Methods: *');
header('Content-Type: application/json');

require_once "../vendor/autoload.php";

$data = json_decode(file_get_contents('php://input'));
send_mail('pansfloyd@gmail.com', 'joe brock', $data);

function send_mail($email, $name, $data) {
    $mail = new PHPMailer(true);

    $mail->SMTPDebug = 3;
    $mail->isSMTP();
    $mail->Host = "smtp.gmail.com";
    $mail->SMTPAuth = true;
    $mail->Username = "dealinmaivasha@gmail.com";
    $mail->Password = "password"; //changed this :D
    $mail->SMTPSecure = "tls";
    $mail->Port = 587;

    $mail->From = "dealinmaivasha@gmail.com";
    $mail->FromName = "Dealin Maivasha";

    $mail->addAddress($email, $name);

    $mail->isHTML(true);

    $mail->Subject = "Subject Text";

    $mail->addAttachment($data->jsonObject); // SO, this is where I need to send image, and this line doesn't work at all
    $mail->Body = "Body";
    $mail->AltBody = "This is the plain text version of the email content";

    try {
        $mail->send();
        echo "Message has been sent successfully";
    } catch (Exception $e) {
        echo "Mailer Error: " . $mail->ErrorInfo;
    }
}

So, the question is, how can I change line with addAttachment so it all would work?

Just in case, I tried to use console.log to see what is in newObject, here’s the result: result in console

As you see, I also got an error in console.

I also tried to use myArray variable in js like that:

  myArray.push(newObject)

And then I tried to send myArray in fetch, but it didn’t work either.

I would be very grateful to any answers and recommendations!

Advertisement

Answer

Have a look at the source for the addAttachment method of PHPMailer. (Pasted to the end of this answer.)

You’re passing an object ($data-> jsonObject) where the method expects a string corresponding to a file path.

The solution could take many forms – you’ve got to find some way to take the submitted data and save at least a temporary file to the server before sending it as an attachment via PHPMailer.

You’re already sending the rest of the data in a Content-type: application/json format, but following some of the approaches in this answer which uses an enctype of multipart/form-data on the form could be one way.

Alternatively, you might convert the image’s data to base64 and POST it with the rest of your JSON data. Then, on the other side, decode & save to /tmp/{filename}.ext and reference THAT as the first arg to $mail->addAttachment.

/**
 * Add an attachment from a path on the filesystem.
 * Never use a user-supplied path to a file!
 * Returns false if the file could not be found or read.
 * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client.
 * If you need to do that, fetch the resource yourself and pass it in via a local file or string.
 *
 * @param string $path        Path to the attachment
 * @param string $name        Overrides the attachment name
 * @param string $encoding    File encoding (see $Encoding)
 * @param string $type        MIME type, e.g. `image/jpeg`; determined automatically from $path if not specified
 * @param string $disposition Disposition to use
 *
 * @throws Exception
 *
 * @return bool
 */
public function addAttachment(
    $path,
    $name = '',
    $encoding = self::ENCODING_BASE64,
    $type = '',
    $disposition = 'attachment'
) {
  ...
}
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement