我有一个带有文件输入的前端表单,任何人(没有注册用户)都可以上传一个图像,该图像将附加到后端的自定义元字段。要预览图像,我使用的是旧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 内置函数来处理上传并将文件移动到媒体库中。我使用隐藏字段来存储id
附件的 WordPress,因此如果用户决定通过上传新图片来更改图片,则旧图片将被删除。这是我的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由于刷新而不存在。
恶意用户可以
attachment
使用不同的 ID 编辑隐藏字段。
我认为将文件上传到文件/temp
夹仅用于预览目的,然后每 X 次运行一次 cron 作业以将其清空。/temp
但是,一旦提交了整个表单,我如何使用 WordPress 功能将图像从图库中移动,以便我可以获取附件 ID 以链接到帖子?
请注意,我有两种形式,一种用于处理图像,另一种是包含将要发布的所有内容的全局表单,因为我可以将新帖子作为“草稿”发布,管理员有权决定。但是如何安全地为图像执行此操作?只有表单发布成功后,如何预览图像并将其放入图库?
我知道 FileReader API,但我需要与 IE8+ 兼容,这样就不行了。我也知道所有 Flash 和 Silverlight 解决方案,但这也不是一个选项。另外请不要只链接到 WordPress 插件,我正在尝试在这里学习。