我有一个带有文件输入的前端表单,其中 anybody (没有注册用户)可以上传将附加到后端自定义元字段的图像。要预览图像,我正在使用旧的iframe
技术。我的表格如下:
<form id="upload-photo" method="post" target="preview-iframe" action="<?= get_template_directory_uri() ?>/inc/upload.php" enctype="multipart/form-data" >
<div id="preview"><img src="" alt="" /></div>
<iframe id="preview-iframe" name="preview-iframe" src=""></iframe>
<input type="file" name="author_photo" />
<input type="hidden" id="attachment" name="attachment" value=""/>
<button type="submit" id="upload">Upload</button>
</form>
然后我使用WordPress内置函数来处理上传并将文件移动到媒体库中。我使用隐藏字段存储附件的WordPress id
,因此如果用户决定通过上传新图片来更改图片,那么旧图片将被删除。这是我的PHP:
<?php
define('WP_USE_THEMES', false);
require_once '../../../../wp-load.php';
require_once(ABSPATH .'wp-admin/includes/image.php');
require_once(ABSPATH .'wp-admin/includes/file.php');
require_once(ABSPATH .'wp-admin/includes/media.php');
if (isset($_POST['attachment'])) {
wp_delete_attachment($_POST['attachment'], true);
}
foreach ($_FILES as $file => $data) {
if ($data['error'] === UPLOAD_ERR_OK) {
$attachment = media_handle_upload($file, null);
}
}
echo wp_get_attachment_image($attachment, 'author', 0, array('id' => $attachment));
?>
最后jQuery将它们粘在一起:
var $preview = $('#preview'),
$iframe = $('#preview-iframe'),
$attachment = $('#attachment');
$('#upload').click(function() {
$iframe.load(function() {
var img = $iframe.contents().find('img')[0];
$preview.find('img').attr('src', img.src);
$attachment.val(img.id);
});
});
一切都很完美,但这种简单的方法几乎没有问题:
如果禁用JavaScript,则图片不会被删除
如果用户上传文件然后刷新网站,然后上传和其他图片,则之前的附件不会被删除,因为之前的附件ID因刷新而不存在。
恶意用户可以使用其他ID编辑隐藏的attachment
字段。
我想将文件上传到/temp
文件夹仅用于预览,然后每隔X次运行一次cron作业以清空它。但是,如果整个表单已经提交,我如何利用WordPress函数将图像从/temp
移动到图库,这样我就可以获得附件ID以链接到帖子?
请注意,我有两个表单,一个用于处理图像,另一个表单包含将要发布的所有内容,并且已经有效,因为我可以将新帖子发布为“草稿”,管理员有权使用决定。但如何安全地为图像做这个?如果表单已成功发布,如何预览图片并将其放入图库?
我知道FileReader API,但我需要IE8 +的兼容性,所以不会这样做。我也知道所有的Flash和Silverlight解决方案,但这也不是一个选择。另外,请不要只链接到WordPress插件,我想在这里学习。
答案 0 :(得分:0)
好吧,我似乎又回答了自己的问题。这就是我解决它的方式。我找到了一个WordPress函数media_handle_sideload
,它允许您从其他位置上传文件,而不仅仅像上一个函数一样从$_FILES
数组中上传文件。
所以我现在采用了我最初的方法,因为我知道这个功能。我基本上将文件上传到/temp
文件夹以进行预览,并为其提供一个唯一的ID,我将其存储到隐藏字段中。当用户提交整个表单并通过验证时,我会获取存储的ID并查明文件是否存在,如果是,我将其移动到库中。这解决了我对安全性的大多数担忧,因为即使恶意用户发现现有的唯一ID(不太可能但可能),该文件也不会像之前那样被删除,而只是移入图库(不是很大)。
最后,我设置了一个cron作业,每隔X个时间清空临时文件夹。