Wordpress在没有插件的情况下将带有多个文件的表单发送到电子邮件



目的是允许用户将自己的新文章材料(文本和文件(发送到管理员的电子邮件中。

有一种形式:

<form class="form form-send" enctype="multipart/form-data">
<div class="send__inputs-block">
<div class="sliding-label__block send__textarea-block">
<textarea name="comment" id="comment" class="input textarea send__textarea" placeholder=" "></textarea>
<label for="comment" class="text text--fz-18 sliding-label">
<?php echo get_post_meta( get_the_ID(), 'joint_send_comment_text', true ); ?>
</label>
</div>
<div class="sliding-label__block">
<input id="name" type="text" name="name" class="input input-text" placeholder=" ">
<label for="name" class="text text--fz-18 sliding-label">
<?php echo get_post_meta( get_the_ID(), 'joint_send_name_text', true ); ?>
</label>
</div>
</div>
<div class="send__file-block">
<input id="file" type="file" name="file" class="input-file" multiple>
<label for="file" class="label label-file">
<i class="joint-upload icon"></i>
<span class="text text--fz-14 upload__text">
<?php echo get_post_meta( get_the_ID(), 'joint_send_file_text', true ); ?>
</span>
</label>
</div>
<button type="submit" class="button form-button">
<span class="button-text">
<?php echo get_post_meta( get_the_ID(), 'joint_send_submit_text', true ); ?>
</span>
</button>
</form>

这是JS代码:

function formSend(e, form) {
e.preventDefault()
if (formValidate(form)) return
let backFile = jointAjax.ajaxurl
let curPage = ''
let formData = new FormData(form)
if (form.classList.contains('form-contacts')) {
curPage = 'contacts'
}
else if (form.classList.contains('form-send')){
curPage = 'send'
let uploadFiles = []
for (let single of form.file.files) {
uploadFiles.push(single)
}
console.log(uploadFiles[0])
formData.append('file', uploadFiles)
}
else {
return
}
formData.append('action', curPage)
fetch(backFile, {
method: 'POST',
body: formData,
})
.then(form.reset())
.catch(error => {
error.json().then(response => {
alert(response.message)
})
})
}

以下是PHP代码:

add_action('wp_ajax_send', 'joint_send_send_form');
add_action('wp_ajax_nopriv_send', 'joint_send_send_form');
function joint_send_send_form() {
global $joint_settings;
$data = json_encode($_POST);
$data = json_decode($data, true);
$attachment = array();
if (isset($_FILES['file'])) {
foreach($_FILES['file'] as $key => $file) {
$attachment[] = $file['tmp_name'] . $file['name'];
}
}
$mailBody = '';
foreach ($data as $key => $value) {
if ($key === 'action' || $key === 'file') continue;
if (!empty($data[$key]))
$mailBody .= '<p><strong>' . ucfirst($key) . ':</strong> ' . esc_html($value) . '</p>';
}
$headers = array(
'From: Joint Admin <' . SMTP_FROM . '>',
'content-type: text/html'
);
wp_mail(
$joint_settings['send_mail_to'],
$joint_settings['send_mail_theme'],
$mailBody,
$headers,
WP_CONTENT_DIR . '\' . $_FILES['file']['name']
);
// wp_send_json_success($_FILES['file']['tmp_name'] . '\' . $_FILES['file']['name']);

}

我已经浏览了各种论坛、文章和视频,但我似乎无法完成任务。

在wp_mail中,我们必须传递文件的完整路径,但从哪里可以获得该路径?无论我如何处理多个文件,函数都只返回最后一个文件的名称作为回复。

SMTP设置正确。收到了电子邮件,但没有文件。

请帮忙,我不知道该怎么办了。

我明白了——我查看了Contact表单7插件中的实现,并理解了原理。

基本想法是首先将上传的文件移动到网站的内部目录,然后从那里发送到电子邮件。

JS中,我只更改了一件事(您可以在不处理的情况下向请求发送文件(:

else if (form.classList.contains('form-send')){
formData.append('file', form.file.files)
curPage = 'send'
}

我的处理程序函数如下所示:

add_action('wp_ajax_send', 'joint_send_send_form');
add_action('wp_ajax_nopriv_send', 'joint_send_send_form');
function joint_send_send_form() {
global $joint_settings;
$data = json_encode($_POST);
$data = json_decode($data, true);
$mailBody = '';
foreach ($data as $key => $value) {
if ($key === 'action' || $key === 'file') continue;
if (!empty($data[$key]))
$mailBody .= '<p><strong>' . ucfirst($key) . ':</strong> ' . esc_html($value) . '</p>';
}
$headers = array(
'From: Joint Admin <' . SMTP_FROM . '>',
'content-type: text/html'
);
$file = $_FILES['file'];
// joint_array_flatten() - converts multi-dimensional array to a flat array
$names = joint_array_flatten( $file['name'] );
$tmp_names = joint_array_flatten( $file['tmp_name'] );
$uploads = wp_get_upload_dir()['basedir'];
$uploads_dir = path_join( $uploads, 'joint_uploads' );
$uploaded_files = array();
foreach ( $names as $key => $filename ) {
$tmp_name = $tmp_names[$key];
if ( empty( $tmp_name ) or ! is_uploaded_file( $tmp_name ) ) {
continue;
}
// joint_antiscript_file_name() - converts a file name to one that is not executable as a script
$filename = joint_antiscript_file_name( $filename );
$filename = wp_unique_filename( $uploads_dir, $filename );
$new_file = path_join( $uploads_dir, $filename );
if ( false === @move_uploaded_file( $tmp_name, $new_file ) ) {
wp_send_json_error( json_encode( array('message' => 'Upload error') ) );
return;
}
// Make sure the uploaded file is only readable for the owner process
chmod( $new_file, 0400 );
$uploaded_files[] = $new_file;
}
wp_mail(
$joint_settings['send_mail_to'],
$joint_settings['send_mail_theme'],
$mailBody,
$headers,
$uploaded_files
);
// Deletes sent files as they are on the email
foreach ( $uploaded_files as $filepath ) {
wp_delete_file( $filepath );
}
}

我从联络表格7偷了几个功能。反脚本肯定很有用,但是否需要joint_array_flatten——我不知道,但我已经太累了,无法再思考了。

最后,我从目录中删除下载的文件,这样它就不会被阻塞。

此外,正如用户@Tangentially Vertical正确指出的那样,您需要在文件输入名称中添加[]才能发送多个文件:

<input id="file" type="file" name="file[]" class="input-file" multiple>

否则,就是这样。我希望有一天这会帮助其他人,他们不必像我一样为类似的任务而苦恼(

相关内容

最新更新