2

我有一个带有文件输入的前端表单,任何人(没有注册用户)都可以上传一个图像,该图像将附加到后端的自定义元字段。要预览图像,我使用的是旧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 插件,我正在尝试在这里学习。

4

1 回答 1

0

好吧,看来我又在回答我自己的问题了。这就是我解决它的方法。我发现了一个 WordPress 函数media_handle_sideload,它可以让您从其他位置上传文件,而不仅仅是$_FILES像以前的函数那样从数组中上传文件。

因此,既然我知道了该功能,我就采用了最初的方法。我基本上将文件上传到一个/temp文件夹以进行预览,并给它一个唯一的 ID,我将其存储到隐藏字段中。当用户提交整个表单并通过验证时,我获取存储的 ID 并确定文件是否存在,如果存在,我将其移动到图库。这解决了我对安全性的大部分担忧,因为即使恶意用户找到现有的唯一 ID(不太可能但可能),该文件也不会像以前那样被删除,而只是移动到图库中(没什么大不了的)。

最后,我设置了一个 cron 作业,每隔 X 时间清空临时文件夹。

于 2013-04-07T21:57:20.300 回答