I’m bulding a form widget with upload field, where the form data is sent via POST request through WordPress REST_API. I’m getting the post response in PHP; composing the mail data and sending through wp_mail() function. But can’t make the upload file be sent with the proper file name and file extension, only the temporary name and .tpm extension.
I’ll post all main functions used through the process just so there’s nothing that may be important left, BUT the key part of the code, and where the problem resides, is the prepare_attachments()
function. That’s where I’m sure the problem is and where I’ll have to implement the fix, so you can just quick read or ignore the rest.
Heres my functions. JS Ajax request
submitData(form) {
let formData = new FormData(form[0]);
jQuery.ajax({
url: '/wp-json/my-plugin/v1/send_email/',
type: 'POST',
data: formData,
processData: false,
contentType: false,
beforeSend: function () {
// validate fields
},
success: function (response) {
// success actions
},
error: function () {
// build error messages
}
});
return false;
}
Rest API Class
<?php
class REST_API {
public function __construct() {
add_action('rest_api_init', [$this, 'register_routes']);
}
public function register_routes(){
register_rest_route('my-plugin/v1', '/send_email/', [
'methods' => 'POST',
'callback' => [$this, 'prepare_mail_data'],
'permission_callback' => '__return_true',
]);
}
public function prepare_mail_data(WP_REST_Request $request) {
$form_data = $request->get_params();
$files = $request->get_file_params();
// ..
$service = new Contact_Form_Service($form_data, $files);
$response = $service->handle();
return [
'response' => $response,
'fields' => $form_data,
'files' => $files,
// ..
];
}
}
And finaly the code responsible for getting the $request->get_params();
data and bulding the mail content with attachment:
<?php
class Contact_Form_Service {
protected $form_data, $files, ..;
public function __construct($form_data, $files) {
$this->form_data = $form_data;
$this->files = $files;
// ..
}
public function handle() {
$response = $this->send_mail(); // send mail
return $response;
}
protected function send_mail(){
$mail_data = $this->compose_mail_data(); // compose all the data
$email = wp_mail(
$mail_data['mail_to'],
$mail_data['mail_subject'],
$mail_data['mail_message'],
$mail_data['headers'],
$mail_data['attachments']
);
return [
'success' => $email,
'data' => [
'message' => '' // get proper message
]
];
}
protected function compose_mail_data(){
// .. previous mail content codes irrelevant to this example
// Prepare attachments
$attachments = $this->prepare_attachments($files);
// Build the data
$mail_data = [
'mail_to' => $settings['email_to'],
'mail_subject' => $settings['email_subject'],
'mail_message' => $content,
'headers' => [
'Content-Type: text/' . $settings['email_content_type'] . '; charset=UTF-8',
'From: ' . $settings['email_from'],
'Reply-To: ' . $settings['email_reply_to'],
],
'attachments' => $attachments
];
return $mail_data;
}
// KEY FUNCTION
protected function prepare_attachments($files) {
$attachments = [];
// Iterate through the files array to extract attachments
if (isset($files['form_fields']['tmp_name']['file'])) {
$tmp_name = $files['form_fields']['tmp_name']['file'];
$error = $files['form_fields']['error']['file'];
if ($error === UPLOAD_ERR_OK) {
// Log the path of each file
error_log('Attachment: ' . $tmp_name);
$attachments[] = $tmp_name;
}
}
return $attachments;
}
}
I’ve tried several methods. Have tried getting the original name of the file instead of the temp name, but then the files aren’t attached; tried uploading to wordpress before attaching; tried to store the original name and extension and replace after, but nothing worked so far.
Here’s the POST response object of the uploaded file to show how the data is submited through my form:
{
"form_fields": {
"name": {
"file": "beatifull-picture.jpeg"
},
"full_path": {
"file": "beatifull-picture.jpeg"
},
"type": {
"file": "image/jpeg"
},
"tmp_name": {
"file": "C:\Windows\Temp\phpD363.tmp"
},
"error": {
"file": 0
},
"size": {
"file": 364006
}
}
}
Thanks in advanced and sorry for the long codes
Expecting to submit the attachment with the proper filename and extension using wp_mail() function. I’ve tried to use different methods on my own; tried chat GPT, tried Copilot; but none of them helped so far.