- Вопрос или проблема
- Ответ или решение
- Реализация загрузки и скачивания изображений на фронтенде WordPress
- Структура системы
- 1. Создание формы для загрузки изображений
- 2. Обработка загрузки изображений на сервере
- 3. Скачивание обработанных изображений
- 4. Удаление изображений
- Создание JavaScript для обработки загрузки
- Заключение
Вопрос или проблема
Я создаю веб-приложение с использованием WordPress, приложение будет включать в себя эту библиотеку, которая будет выполнять некоторые операции стеганографии. Мне нужна помощь, чтобы понять, как реализовать загрузку изображений на стороне клиента для пользователей, которые хотят использовать приложение. Я создал форму bs4, которая включает в себя поле для загрузки файлов и текстовую область для сообщения, которое будет включено в изображение, а также вторую форму, которая будет обрабатывать изображения, содержащие скрытые данные. Мне нужно загрузить изображение, а затем позволить пользователю скачать его до того, как система удалит изображение. Это возможно? Как мне управлять потоками загрузки и скачивания в WP?
Я работаю над этим кодом для фронтенда ERP-приложения.
Обратите внимание, что только после загрузки будет возможно вставить сообщение.
Вам нужно будет нажать «Редактировать», чтобы открыть модальное окно и ввести содержимое.
Может быть, это будет полезно для вас!
Вставьте в ваш functions.php
<?php
if(!is_admin()){
if(!function_exists('ajax_upload_files')):
function ajax_upload_files(){
wp_enqueue_script('ajax-upload-files', get_template_directory_uri().'js/upload-files.js',array('jquery','plupload-handlers'), wp_get_theme()->get( 'Version' ), true);
wp_localize_script('ajax-upload-files', 'ajax_vars_files',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('o_files'),
'theme_url' => get_template_directory_uri(),
'number' => 1,
'upload_enabled' => true,
'plupload' => array(
'runtimes' => 'html5,flash,html4',
'browse_button' => 'aaiu-uploader',
'container' => 'aaiu-upload-container',
'file_data_name' => 'aaiu_upload_file_files',
'max_file_size' => get_option('max_files'),
'max_files' => get_option('max_file_size'),
'url' => admin_url('admin-ajax.php') . '?action=o_upload_files&post_ID='.get_the_ID(),
'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'),
'filters' => array(
array(
'title' => 'Accepted files',
'extensions' => "jpg,jpeg,png,gif"
)//,bmp,ico,tiff,mp3,mp4,mov,avi,wmv,wav,midi,mid,zip,rar...
),
'multipart' => true,
'urlstream_upload' => true,
'prevent_duplicates' => true,
)
)
);
}
add_action( 'wp_enqueue_scripts', 'ajax_upload_files', 100 );
endif;
if( !function_exists('O_upload_files') ):
function O_upload_files() {
$file = array(
'name' => sanitize_text_field($_FILES['aaiu_upload_file_files']['name']),
'type' => sanitize_text_field($_FILES['aaiu_upload_file_files']['type']),
'tmp_name' => sanitize_text_field($_FILES['aaiu_upload_file_files']['tmp_name']),
'error' => sanitize_text_field($_FILES['aaiu_upload_file_files']['error']),
'size' => sanitize_text_field($_FILES['aaiu_upload_file_files']['size']),
);
$file = O_fileupload_process_files($file);
}
endif;
add_action('wp_ajax_o_upload_files', 'O_upload_files');
add_action('wp_ajax_nopriv_o_upload_files', 'O_upload_files');
if( !function_exists('O_handle_file_files') ):
function O_handle_file_files($upload_data) {
$return = false;
$uploaded_file = wp_handle_upload($upload_data, array('test_form' => false));
if (isset($uploaded_file['file'])) {
$parent_post_id = intval($_REQUEST['post_ID']);
$file_loc = $uploaded_file['file'];
$file_name = basename($upload_data['name']);
$file_type = wp_check_filetype($file_name);
$attachment = array(
'post_mime_type' => $file_type['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($file_name)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $file_loc, $parent_post_id);
$attach_data = wp_generate_attachment_metadata($attach_id, $file_loc);
wp_update_attachment_metadata($attach_id, $attach_data);
$return = array('data' => $attach_data, 'id' => $attach_id, 'parent_post_ID' => $parent_post_id);
return $return;
}
return $return;
}
endif;
if( !function_exists('O_fileupload_process_files') ):
function O_fileupload_process_files($file) {
$attachment = O_handle_file_files($file);
if (is_array($attachment)) {
$html = O_get_html_files($attachment);
//update_post_meta($attachment['id'],'_set_type_files',$attachment['parent_post_ID']);
echo json_encode(array('success' => true,'html' => $html,'attach' => $attachment['id']));
exit;
}
echo json_encode(array('success' => false));
exit;
}
endif;
if( !function_exists('O_get_html_files') ):
function O_get_html_files($attachment) {
$attach_id = $attachment['id'];
$post = get_post($attach_id);
$dir = wp_upload_dir();
$path = $dir['baseurl'];
$file = $attachment['data']['file'];
$html="";
$html .= $path."https://wordpress.stackexchange.com/".$file;
return $html;
}
endif;
if( !function_exists('O_update_attachment') ):
function O_update_attachment() {
check_ajax_referer('o_files', 'security');
global $wpdb;
$post = get_post($_REQUEST['attachment_ID']);
$return = $wpdb->update(
$wpdb->posts,
array(
'post_title' => stripslashes($_POST['file_new_title']),
'post_content' => stripslashes($_POST['file_new_content']),
'post_modified' => date("Y-m-d H:i:s"),
'post_modified_gmt' => gmdate("Y-m-d H:i:s")
),
array( 'ID' => $post->ID )
);
if(is_wp_error($return)) {
echo json_encode(array('save'=>false, 'message'=>$return->get_error_message()));
exit();
}
echo json_encode(array('save'=>true, 'message'=>'Готово'));
}
add_action( 'wp_ajax_o_update_attachment', 'O_update_attachment' );
endif;
if( !function_exists('O_remove_attachment') ):
function O_remove_attachment() {
check_ajax_referer('o_files', 'security');
$post = get_post($_REQUEST['attachment_ID']);
$return = wp_delete_attachment($post->ID);
if(is_wp_error($return)) {
echo json_encode(array('save'=>false, 'message'=>$return->get_error_message()));
exit();
}
echo json_encode(array('save'=>true, 'message'=>'Готово'));
}
add_action( 'wp_ajax_o_remove_attachment', 'O_remove_attachment' );
endif;
}//!is_admin
?>
Сохраните следующий код в папке js/ вашего шаблона: “upload-files.js”
(function($) {
"use strict";
var ajaxURL = ajax_vars_files.ajaxurl;
//var max = ajax_vars_files.plupload.max_files;
var max = 1;
var newFile="";
if (typeof(plupload) !== 'undefined') {
var uploader_files = new plupload.Uploader(ajax_vars_files.plupload);
uploader_files.init();
uploader_files.bind('FilesAdded', function(up, files) {
var filesNo = 0;
$.each(files, function(i, file) {
if(filesNo < max) {
$('#aaiu-upload-files').append(
'<div id="' + file.id + '" class="push-5 sending-upload"><i class="fa fa-circle-o-notch fa-spin text-default"></i> ' +
file.name + ' (' + plupload.formatSize(file.size) + ') <div></div>' +
'</div>');
}
filesNo = filesNo + 1;
});
up.refresh();
uploader_files.start();
});
uploader_files.bind('UploadProgress', function(up, file) {
$('#' + file.id + " div").html('<div class="progress progress-sm progress-striped active"><div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="'+ file.percent +'" aria-valuemin="0" aria-valuemax="100" style="width: ' + file.percent + '%" data-toggle="tooltip" title="'+ file.percent +'">[ '+ (file.percent-2) +'% ] ...</span></div><hr>');
});
// В случае ошибки
uploader_files.bind('Error', function(up, err) {
$('#aaiu-upload-files').append("<div>Ошибка: " + err.code +
", Сообщение: " + err.message +
(err.file ? ", Файл: " + err.file.name : "") +
"</div>"
);
swal('ОШИБКА', err.file.name, 'error');
up.refresh();
});
uploader_files.bind('FileUploaded', function(up, file, response) {
var result_files = $.parseJSON(response.response);
$('#' + file.id).remove();
if (result_files.success) {
if($('#imagelist .uploaded_images').length < max) {
newFile += '~~~' + result_files.attach;
$('#new_file').val(newFile);
$('#imagelist').append('<div class="uploaded_images push-10 label label-success" data-imageid="' + result_files.attach + '"><i class="fa fa-check"></i> ' + file.name + '</div>');
if($('#imagelist .uploaded_images').length >= max) {
$('#aaiu-uploader').hide();
}
$('#reload-gallery').trigger('click');
} else {
alert('Превышен лимит');
}
}else{
alert('Произошла ошибка');
}
});
$('#aaiu-uploader').click(function(e) {
uploader_files.start();
e.preventDefault();
});
}
//триггер
$(document).on("click","#reload-gallery", function(){
var post_ID = $(this).val();
$.ajax({
type: 'GET',
data:{
action: 'load'
},
cache: false,
url: ajax_vars_files.theme_url+'attachments.php?post_ID='+post_ID,
success: function(response){
$('#load-gallery').html(response);
},
error: function(response){
$('#load-gallery').html('<strong>ОШИБКА:</strong> '+console.log(response));
}
});
});
$(document).on("click",".btn-modal", function(){
var attachment_ID = $(this).attr('data-attachment-id');
$.ajax({
type: 'GET',
data:{
action: 'load',
},
cache: false,
url: ajax_vars_files.theme_url+'attachment-modal.php?attachment_ID='+attachment_ID,
success: function(response){
$('#load-request').html(response);
$('#modal-files').modal('show');
},
error: function(response){
$('#error-files').html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><h3 class="font-w300 push-15">ОШИБКА</h3>'+console.log(response)+'</div>');
}
});
});
$(document).on("click","#save-file-metadata", function(){
var data = {
'action' : 'o_update_attachment',
'security' : ajax_vars_files.nonce
};
$.ajax({
type: 'POST',
cache: false,
url: ajaxURL,
data: $('form#form-edit-file').serialize()+ '&' + $.param(data),
success: function(response){
if(response.save===true){
$('#modal-files').modal('hide');
setTimeout(function() {
alert('Готово');
$('#reload-gallery').trigger('click');
}, 1000);
}else{
$('#error-files').html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><h3 class="font-w300 push-15">ОШИБКА:</h3> '+response.message+'</div>');
}
},
error: function(response){
$('#error-files').html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><h3 class="font-w300 push-15">ОШИБКА:</h3> '+console.log(response)+'</div>');
}
});
});
$(document).on("click","#remove-file", function(){
var data = {
'action' : 'o_remove_attachment',
'security' : ajax_vars_files.nonce
};
$.ajax({
type: 'POST',
cache: false,
url: ajaxURL,
data: $('form#form-edit-file').serialize()+ '&' + $.param(data),
success: function(response){
if(response.save===true){
$('#modal-files').modal('hide');
setTimeout(function() {
alert('Готово');
$('#reload-gallery').trigger('click');
}, 1000);
}else{
$('#error-files').html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><h3 class="font-w300 push-15">ОШИБКА:</h3> '+response.message+'</div>');
}
},
error: function(response){
$('#error-files').html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><h3 class="font-w300 push-15">ОШИБКА:</h3> '+console.log(response)+'</div>');
}
});
});
})(jQuery);
Сохраните следующий код в корне вашего шаблона: “attachments.php”
<?php
if(isset($_GET['post_ID'])){
$parse_uri = explode('wp-content', $_SERVER['SCRIPT_FILENAME']);
require_once($parse_uri[0] . 'wp-load.php');
$post_ID = $_GET['post_ID'];
}else{
global $post;
$post_ID = $post->ID;
}
$file_attachments = get_posts( array(
'post_type' => 'attachment',
'nopaging' => true,
'cache_results' => true,
'post_parent' => $post_ID,
'order' => 'ASC',
) );
foreach ( array_reverse($file_attachments) as $attachment ):
$file_name_link = wp_get_attachment_link( $attachment->ID, false );
$file_title = apply_filters( 'the_title', $attachment->post_title);
$file_content = $attachment->post_content;
$attachment_url = wp_get_attachment_url($attachment->ID);
$image = wp_get_attachment_image_src($attachment->ID, 'medium', true )[0];
echo '<div class="col-md-3 attachments-grid">';
echo '<img src="'.$image.'" width="100%">';
echo $file_title.'<br>';
echo $file_content.'<br>';
echo '<a href="'.$attachment_url.'" target="_blank">Скачать</a>';
echo '<a class="btn-modal" data-attachment-id="'.$attachment->ID.'">Редактировать</a>';
echo '</div>';
endforeach;
wp_reset_postdata();
wp_reset_query();
Сохраните следующий код в корне вашего шаблона: “attachment-modal.php “
<?php
if(isset($_REQUEST['attachment_ID'])){
$parse_uri = explode('wp-content', $_SERVER['SCRIPT_FILENAME']);
require_once($parse_uri[0] . 'wp-load.php');
$post = get_post($_REQUEST['attachment_ID']);
?>
<div class="modal fade" id="modal-files" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-popout">
<div class="modal-content">
<div class="block block-themed block-transparent remove-margin-b">
<div class="block-header bg-primary-dark">
<ul class="block-options">
<li>
<button data-dismiss="modal" type="button"><i class="fa fa-close"></i></button>
</li>
</ul>
<h3 class="block-title">ФАЙЛ: "<?php echo $post->post_title;?>"</h3>
</div>
<div class="block-content row">
<span id="error-files"></span>
<div class="col-lg-8">
<form id="form-edit-file" name="form-edit-file">
<div class="form-group">
<div class="form-material">
<input class="form-control" value="<?php echo $post->post_title;?>" name="file_new_title" type="text">
<label for="material-text">Название</label>
</div>
</div>
<div class="form-group">
<div class="form-material">
<textarea class="form-control" name="file_new_content" rows="3"><?php echo $post->post_content;?></textarea>
<label for="material-textarea-small">Описание</label>
</div>
</div>
<input value="<?php echo $post->ID;?>" name="attachment_ID" type="hidden">
</form>
</div>
<div class="col-lg-4">
<?php
$type = get_post_mime_type($post->ID);
switch ($type) {
case 'image/jpeg':
case 'image/jpg':
case 'image/png':
case 'image/gif':
case 'application/jpg':
$file = wp_get_attachment_image( $post->ID, array('700', '600'), "", array( "class" => "img-responsive" ) );
break;
}
echo $file;
?>
</div>
</div>
</div>
<div class="modal-footer">
<button id="remove-file" class="btn btn-sm btn-danger pull-left" type="button"><i class="fa fa-trash"></i> Удалить</button>
<button id="save-file-metadata" class="btn btn-sm btn-success" type="button"><i class="fa fa-save"></i> Сохранить</button>
</div>
</div>
</div>
</div>
<?php
}
?>
Это на фронте, на вашей странице единичного элемента
<div class="submit_container">
<div id="upload-container">
<div id="aaiu-upload-container">
<a href="https://wordpress.stackexchange.com/questions/355741/javascript:void(0);" id="aaiu-uploader" class="btn btn-o btn-info push btn-block"><i class="fa fa-folder-open pull-left"></i> Прикрепить</a>
<div id="aaiu-upload-imagelist"></div>
<div id="imagelist"></div>
<div class="clearfix"></div>
<input type="hidden" name="new_file" id="new_file">
</div>
</div>
</div>
<?php echo '<button value="'.$post->ID.'" id="reload-gallery" type="button" class="blank"></button>';?>
<div id="load-gallery">
<?php require_once(get_template_directory().'attachments.php');?>
</div>
<div id="load-request"></div>
Другой способ…
https://developer.wordpress.org/reference/functions/media_sideload_image/
<?php
$insert_post = array(
'post_author' => 1,//или get_current_user_id()
'post_status' => 'publish',
'post_type' => 'attachment',
'post_name' => 'attachment'.date('Ymd-H-i-s'),
'post_date' => date('Y-m-d H:i:s',time()),
);
$post = get_post(wp_insert_post($insert_post));
if(is_wp_error($post->ID)){
echo $post->ID->get_error_message();
}
require_once(ABSPATH.'wp-admin/includes/media.php');
require_once(ABSPATH.'wp-admin/includes/file.php');
require_once(ABSPATH.'wp-admin/includes/image.php');
media_sideload_image($_POST['file_url'],$post->ID,stripslashes($_POST['message']));
$file_attachments = get_posts( array(
'post_type' => 'attachment',
'nopaging' => true,
'cache_results' => false,
'post_parent' => $post->ID,
'order' => 'ASC',
) );
//печать URL файла для загрузки
foreach ($file_attachments as $attachment){
echo wp_get_attachment_url($attachment->ID).'<br>';
}
?>
И для удаления файла и поста…
<?php
if(isset($_POST['param']) && $_POST['param']=='value'){
//check_ajax_referer('nonce', 'security');
//$attachment_ID = $_POST['attachment_ID'];
$post_ID = $_POST['post_ID'];
wp_delete_post($post_ID, true);// false: не удалять и отправить в корзину / true: пропустить корзину: удалить окончательно
$file_attachments = get_posts( array(
'post_type' => 'attachment',
'nopaging' => true,
'cache_results' => false,
'post_parent' => $post_ID,
'order' => 'ASC',
) );
if(isset($file_attachments)) {
foreach($file_attachments as $attachment){
//https://developer.wordpress.org/reference/functions/wp_delete_attachment/
wp_delete_attachment($attachment->ID,true);// true: принудительное удаление файла
}
}
}
?>
Ответ или решение
Реализация загрузки и скачивания изображений на фронтенде WordPress
Ваша задача заключается в создании веб-приложения на основе WordPress, которое позволяет пользователям загружать изображения для операций стеганографии с использованием библиотеки Morpheus. Ниже изложен полный сценарий для реализации загрузки изображений и их последующей обработки с возможностью скачивания.
Структура системы
Для реализации необходимы следующие ключевые элементы:
- Форма для загрузки изображений.
- Обработка загрузки на сервере.
- Методы для скачивания обработанных изображений.
- Удаление изображений после скачивания для обеспечения безопасности.
1. Создание формы для загрузки изображений
Вам необходимо создать HTML-форму, содержащую поле для загрузки изображений и текстовое поле для ввода сообщения, которое будет закодировано в изображении. Пример кода HTML для формы:
<div class="submit_container">
<div id="upload-container">
<div id="aaiu-upload-container">
<a href="javascript:void(0);" id="aaiu-uploader" class="btn btn-o btn-info push btn-block">
<i class="fa fa-folder-open pull-left"></i> Прикрепить
</a>
<div id="aaiu-upload-imagelist"></div>
<div id="imagelist"></div>
<div class="clearfix"></div>
<input type="hidden" name="new_file" id="new_file">
</div>
</div>
<button value="<?= $post->ID ?>" id="reload-gallery" type="button" class="blank"></button>
<div id="load-gallery">
<?php require_once(get_template_directory() . 'attachments.php'); ?>
</div>
<div id="load-request"></div>
</div>
2. Обработка загрузки изображений на сервере
Для обработки загрузки изображений вам необходимо настроить AJAX-запросы и соответствующие функции в файле functions.php
. Код, который вы предоставили, содержит большинство необходимых функций, свяжите их с обработчиком AJAX.
Вот пример ключевых функций:
function O_upload_files() {
$file = $_FILES['aaiu_upload_file_files'];
// Здесь вы можете применять валидацию файла и обработку.
$attachment = O_handle_file_files($file);
if (is_array($attachment)) {
// Обработка успешной загрузки
echo json_encode(array('success' => true, 'attach' => $attachment['id']));
} else {
echo json_encode(array('success' => false));
}
exit;
}
add_action('wp_ajax_o_upload_files', 'O_upload_files');
add_action('wp_ajax_nopriv_o_upload_files', 'O_upload_files');
3. Скачивание обработанных изображений
После того как изображение загружено и обработано, вы можете предоставить пользователю возможность его скачать. Это можно сделать через функцию, которая выводит ссылку на скачивание.
Измените файл attachments.php
для добавления ссылки на скачивание:
echo '<a href="' . esc_url($attachment_url) . '" target="_blank">Скачать</a>';
4. Удаление изображений
Для удаления изображений после скачивания вы можете создать AJAX-запрос, который будет вызываться после того, как задача завершена. Это может быть сделано с использованием следующего кода в functions.php
:
function O_remove_attachment() {
// Проверка nonce для обеспечения безопасности
check_ajax_referer('o_files', 'security');
$attachment_ID = $_POST['attachment_ID'];
if(wp_delete_attachment($attachment_ID, true)) {
echo json_encode(array('save' => true, 'message' => 'Удалено'));
} else {
echo json_encode(array('save' => false, 'message' => 'Ошибка'));
}
exit;
}
add_action('wp_ajax_o_remove_attachment', 'O_remove_attachment');
Создание JavaScript для обработки загрузки
Ваш JavaScript должен обрабатывать события загрузки файлов, отправку данных на сервер и отображение статуса загрузки, как показано в приведенном вами коде в файле upload-files.js
.
var uploader_files = new plupload.Uploader(ajax_vars_files.plupload);
uploader_files.bind('FilesAdded', function(up, files) {
// Добавление логики вывода информации о загружаемых файлах
});
Заключение
Теперь у вас есть четкая схема для реализации процесса загрузки и скачивания изображений в веб-приложении на базе WordPress. Используя представленные функции и JavaScript, ваша система сможет поддерживать целевую функциональность с учетом безопасности и удобства для пользователя. Обязательно проведите тестирование, чтобы убедиться, что все работает корректно и предотвращаются возможные уязвимости.