- Вопрос или проблема
- Ответ или решение
- Создание фронтенд-формы для загрузки изображений в WordPress
- Основная структура HTML-формы
- JavaScript для асинхронной загрузки
- Серверная обработка загрузки изображений
- Обработка создания поста и привязка изображений
- Удаление ненужных изображений при отмене загрузки
- Заключение
Вопрос или проблема
Я создаю фронтенд-форму для загрузки изображений. Форма создает новый пост:
...обработка поста...
$application_id = wp_insert_post($application);
Я затем использую media_handle_upload
для загрузки изображения и прикрепления его к посту:
...обработка файла...
$file_id = media_handle_upload("upload_file", $application_id);
Все работает хорошо — моя проблема заключается в том, что загрузка файлов происходит только после нажатия пользователем кнопки отправки.
Существует ли способ загружать изображения сразу, когда пользователь добавляет их в поле ввода? Что произойдет, если пользователь затем покинет форму — как я смогу удалить изображения?
Убедиться, что ваша форма загружает изображение сразу после его выбора, а не после отправки, довольно просто, так как вы можете отправить форму при изменении любого поля вот так:
<form action="http://example.com" method="post" action="#">
<input type="file" onchange="form.submit()" />
</form>
Сложность заключается в отслеживании этого на стороне сервера. Пользователь может изменить свое решение и выбрать другое изображение. Поэтому вы хотите сохранить только те данные, которые находятся в форме, когда пользователь нажимает кнопку отправки. Если есть только одно изображение, это все еще довольно просто: просто удалите все прикрепленные файлы, которые вы создали, кроме последнего. Но если есть несколько полей ввода файлов, ваша администрация становится немного более сложной.
Тем не менее, если вы посмотрите на media_handle_upload
, вы увидите, что есть возможность передать $post_data
для загружаемого файла. Вы можете, например, использовать поле аннотации (временное) для хранения вашей администрации. Чтобы передать эти административные данные из формы на сервер, вы можете использовать скрытые поля. Ваша форма может выглядеть примерно так:
<form action="http://example.com" method="post" action="#">
// скрытое поле с id созданного поста
<input type="hidden" name="post_id" id="post_id" value="99999" />
<input type="file" name="image_upload1" id="image_upload1" onchange="form.submit()" />
<input type="file" name="image_upload2" id="image_upload2" onchange="form.submit()" />
<input id="submit_my_image" name="submit_my_image" type="submit" value="Загрузить" />
</form>
Теперь, когда форма отправляется (либо с помощью JavaScript, либо с помощью действия отправки), на сервер поступают данные, указывающие имя файла для загрузки. Вы создаете прикрепление к посту:
$post_data['excerpt'] = 'image1';
$file_id = media_handle_upload("image_upload1", $application_id, $post_data);
$post_data['excerpt'] = 'image2';
$file_id = media_handle_upload("image_upload2", $application_id, $post_data);
Если пользователь часто меняет свое мнение, у вас будет довольно много прикреплений с теми же $post_data, но с разными временными метками. Вы можете провести очистку, перебрав все прикрепления при реальной отправке. Или вы можете проверить, существует ли файл с той же аннотацией, прежде чем вы вызовете media_handle_upload
выше.
Теперь вам нужно различать отправки JavaScript и окончательную отправку. Мое предложение — изменить имя кнопки отправки при наведении/нажатии. В этот момент вы также можете очистить аннотации.
Теперь, что если пользователь совсем abandons процесс? Вышеуказанное будет работать только если вы создадите пост в момент, когда показываете форму (или, по крайней мере, при первой загрузке изображения, так как вы не можете иметь прикрепление к несуществующему посту). Фишка здесь в том, чтобы определить свой собственный post_status
, который вы задаете во время вызова wp_insert_post
. Только когда пользователь отправляет, вы изменяете post_status
на draft
или publish
. Периодически вы выполняете автоматическую очистку всех постов, включая прикрепления, данного самостоятельно определенного типа, которые старше трех часов или около того.
Попробуйте ниже код фронтенд-формы с загрузкой медиафайлов в WordPress.
<form id="post-submission-form" method="post" enctype="multipart/form-data">
<input type="file" id="upload_file" name="upload_file" accept="image/*" required>
<input type="submit" value="Отправить пост">
</form>
<div id="image-preview"></div>
<script>
jQuery(document).ready(function($) {
$('#upload_file').change(function() {
var file_data = $(this).prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
$.ajax({
url: ajaxurl, // URL AJAX WordPress
type: 'POST',
data: form_data,
contentType: false,
processData: false,
success: function(response) {
$('#image-preview').html('<img src="' + response + '" />');
}
});
});
$('#post-submission-form').submit(function(e) {
e.preventDefault();
var form = $(this);
var formData = new FormData(form[0]);
$.ajax({
url: ajaxurl,
type: 'POST',
data: formData,
contentType: false,
processData: false,
success: function(response) {
console.log(response);
// Обработайте ответ на отправку поста здесь
}
});
});
});
</script>
funcitons.php
add_action('wp_ajax_upload_image', 'upload_image_callback');
add_action('wp_ajax_nopriv_upload_image', 'upload_image_callback');
function upload_image_callback() {
$uploaded_file = $_FILES['file'];
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($uploaded_file, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
echo $movefile['url'];
} else {
echo 'Ошибка загрузки файла.';
}
die();
}
if(isset($_FILES[‘fileToUpload’]) && !empty($_FILES[‘fileToUpload’][‘name’])){
require_once( ABSPATH . ‘wp-admin/includes/image.php’ );
require_once( ABSPATH . ‘wp-admin/includes/file.php’ );
require_once( ABSPATH . ‘wp-admin/includes/media.php’ );
$attachement_id = media_handle_upload('fileToUpload',$post_id);
if(is_wp_error($attachement_id)){
echo 'Ошибка загрузки !!';
}else{
set_post_thumbnail($post_id,$attachement_id);
}
}
return $post_id ? 'пост успешно создан' : 'ошибка при создании поста ';
.
Ответ или решение
Создание фронтенд-формы для загрузки изображений в WordPress
При разработке фронтенд-формы для загрузки изображений, которая будет создавать новый пост, важно учитывать несколько ключевых аспектов, включая обработку изображения сразу после выбора и организацию системы для управления несколькими загрузками. Ниже представлена детальная инструкция по решению этой задачи с использованием media_handle_upload
в WordPress.
Основная структура HTML-формы
Для начала создадим простую HTML-форму, которая будет содержать поле для загрузки изображений и кнопку для отправки данных:
<form id="post-submission-form" method="post" enctype="multipart/form-data">
<input type="file" id="upload_file" name="upload_file" accept="image/*" required>
<input type="submit" value="Создать пост">
</form>
<div id="image-preview"></div>
Здесь мы используем атрибут enctype="multipart/form-data"
для корректной обработки изображения на серверной стороне.
JavaScript для асинхронной загрузки
Для загрузки изображения сразу после его выбора используем JavaScript (jQuery):
<script>
jQuery(document).ready(function($) {
$('#upload_file').change(function() {
var file_data = $(this).prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
form_data.append('action', 'upload_image'); // Укажите действие для WordPress AJAX
$.ajax({
url: ajaxurl, // URL для AJAX в WordPress
type: 'POST',
data: form_data,
contentType: false,
processData: false,
success: function(response) {
$('#image-preview').html('<img src="' + response + '" />');
}
});
});
$('#post-submission-form').submit(function(e) {
e.preventDefault();
var form = $(this);
var formData = new FormData(form[0]);
$.ajax({
url: ajaxurl,
type: 'POST',
data: formData,
contentType: false,
processData: false,
success: function(response) {
console.log(response);
// Обработайте ответ после отправки поста
}
});
});
});
</script>
В этом коде реализована функция, которая автоматически отправляет загружаемое изображение на сервер, а затем отображает предварительный просмотр изображения на странице.
Серверная обработка загрузки изображений
Теперь создадим функцию для обработки загрузки изображений на стороне сервера. В файле functions.php
добавим следующий код:
add_action('wp_ajax_upload_image', 'upload_image_callback');
add_action('wp_ajax_nopriv_upload_image', 'upload_image_callback');
function upload_image_callback() {
if (isset($_FILES['file'])) {
$uploaded_file = $_FILES['file'];
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($uploaded_file, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
echo $movefile['url']; // Возвращаем URL загруженного изображения
} else {
echo 'Ошибка загрузки файла.';
}
}
die();
}
Эта функция обрабатывает файл, переданный через AJAX, и использует wp_handle_upload
для его загрузки. Если загрузка успешна, URL загруженного файла возвращается обратно на фронтэнд.
Обработка создания поста и привязка изображений
После того, как пользователь завершит загрузку изображений и нажмет на кнопку отправки формы, мы можем создать пост и прикрепить загруженные изображения:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$application_id = wp_insert_post($application); // Создание нового поста
if (isset($_FILES['upload_file']) && !empty($_FILES['upload_file']['name'])) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');
$attachment_id = media_handle_upload('upload_file', $application_id);
if (is_wp_error($attachment_id)) {
echo 'Ошибка загрузки изображения.';
} else {
set_post_thumbnail($application_id, $attachment_id); // Установка изображения миниатюры
}
}
}
Удаление ненужных изображений при отмене загрузки
Если пользователь решит отменить процесс или форма будет отправлена без загрузки, важно удалить временные изображения. Это можно сделать, создавая специальный тип поста с определенным статусом. При окончательной отправке формы измените статус на draft
или publish
.
Запланируйте периодическую проверку и удаление таких постов, которые были созданы около нескольких часов назад и имеют статус, например, temp
.
Заключение
Следуя указанным шагам, вы можете создать эффективную систему для загрузки изображений через фронтенд-форму в WordPress, обеспечивая при этом удобное управление загружаемыми файлами и постами. Не забывайте тестировать все этапы взаимодействия для обеспечения надежности и эффективности вашей системы.