【问题标题】:How to integrate Dropzonejs with wordpress media handler in frontend?如何在前端将 Dropzonejs 与 wordpress 媒体处理程序集成?
【发布时间】:2015-06-07 07:23:39
【问题描述】:

如何将 Dropzonejs 文件上传库集成到 wordpress 前端,就像内置的一样,并在我的媒体库中提供上传的文件?

【问题讨论】:

  • 现在已经四年多了,是时候接受你的答案了:)

标签: wordpress file-upload dropzone.js


【解决方案1】:

Dropzonejs 是一个非常广泛的 JavaScript 库,它提供了许多处理媒体上传的选项。

要将 dropzonejs 与 wordpress 集成,过程非常简单。假设以下代码是您希望显示上传者的位置。

<div id="media-uploader" class="dropzone"></div>
<input type="hidden" name="media-ids" value="">

拥有dropzone 类将自动将dropzone 事件与元素关联。这将阻止我们覆盖默认参数。所以我们想禁用库的自动发现功能。

// Disabling autoDiscover, otherwise Dropzone will try to attach twice.
Dropzone.autoDiscover = false;

现在我们将使用jQuery 将我们的配置与元素绑定。

jQuery("#media-uploader").dropzone({
    url: dropParam.upload,
    acceptedFiles: 'image/*',
    success: function (file, response) {
        file.previewElement.classList.add("dz-success");
        file['attachment_id'] = response; // push the id for future reference
        var ids = jQuery('#media-ids').val() + ',' + response;
        jQuery('#media-ids').val(ids);
    },
    error: function (file, response) {
        file.previewElement.classList.add("dz-error");
    },
    // update the following section is for removing image from library
    addRemoveLinks: true,
    removedfile: function(file) {
        var attachment_id = file.attachment_id;        
        jQuery.ajax({
            type: 'POST',
            url: dropParam.delete,
            data: {
                media_id : attachment_id
            }
        });
        var _ref;
        return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;        
    }
});

在上面的代码中,我们所做的是我们将 dropzone 与带有一些参数的元素附加在一起 ​​-

  • url - 我们要发送文件上传的位置。稍后我会初始化变量。
  • acceptedFiles - 因为我们只对上传图片感兴趣,所以我们将限制文件只附加到图片上。您可以在该图书馆的网站上找到更多信息。
  • success - 文件/图像上传成功时触发的回调。它接受两个参数,上传文件本身的引用和服务器的响应。这很重要,这里我们将附件 id 存储在我们的表单中。您可以在存储 ID 之前在此处执行验证。
  • error - 如果文件上传失败,您可以在这里执行任何任务。
  • addRemoveLinks - 在预览面板下方添加删除文件链接,您可以使用 css 对其进行样式设置。
  • removedfile - 在您单击预览面板中的图像的remove file 链接时处理操作。在这个函数中,我们向我们的服务器发送了一个ajax 调用以从库中删除图像

当然有很多可用的选项,但我发现这些是设置拖放媒体上传器所需的最基本参数。

现在最重要的是决定文件上传器的 url。您可以在其中处理操作的自定义文件。但我找到了另一种方法。

From this question and the answer 我发现使用admin-post.php 文件非常棒。

很多人抱怨这个admin-post.php,所以认为坚持wp_ajax.php 是最好的选择。

所以我在 dropzone 初始化之前初始化了 drophandler 变量,如下所示-

wp_enqueue_script('dropzone','path/to/dropzone', array('jquery'));
wp_enqueue_script('my-script','path/to/script',array('jquery','dropzone'));
$drop_param = array(
  'upload'=>admin_url( 'admin-ajax.php?action=handle_dropped_media' ),
  'delete'=>admin_url( 'admin-ajax.php?action=handle_deleted_media' ),
)
wp_localize_script('my-script','dropParam', $drop_param);

现在我们已准备好将图像发送到服务器。这里我们将在主题的function.php 文件或我们的插件文件中添加一些php 代码,但我们需要确保它已加载。

以下函数将负责上传图片并在库中保存为附件。

add_action( 'wp_ajax_handle_dropped_media', 'handle_dropped_media' );

// if you want to allow your visitors of your website to upload files, be cautious.
add_action( 'wp_ajax_nopriv_handle_dropped_media', 'handle_dropped_media' );



function handle_dropped_media() {
    status_header(200);

    $upload_dir = wp_upload_dir();
    $upload_path = $upload_dir['path'] . DIRECTORY_SEPARATOR;
    $num_files = count($_FILES['file']['tmp_name']);

    $newupload = 0;

    if ( !empty($_FILES) ) {
        $files = $_FILES;
        foreach($files as $file) {
            $newfile = array (
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'tmp_name' => $file['tmp_name'],
                    'error' => $file['error'],
                    'size' => $file['size']
            );

            $_FILES = array('upload'=>$newfile);
            foreach($_FILES as $file => $array) {
                $newupload = media_handle_upload( $file, 0 );
            }
        }
    }

    echo $newupload;    
    die();
}

以下操作负责删除媒体元素。 wp_delete_attachment() 函数的第二个参数允许我们决定是要丢弃图像还是完全删除它。我想完全删除它所以通过true

add_action( 'wp_ajax_handle_deleted_media', 'handle_deleted_media' );

function handle_deleted_media(){

    if( isset($_REQUEST['media_id']) ){
        $post_id = absint( $_REQUEST['media_id'] );

        $status = wp_delete_attachment($post_id, true);

        if( $status )
            echo json_encode(array('status' => 'OK'));
        else
            echo json_encode(array('status' => 'FAILED'));
    }

    die();
}

这将在响应中返回attachment_id,我们将在成功函数中得到它。在media_handle_upload( $file, 0 ); 中,我传递了文件的引用和0,因为我还不想为媒体分配任何帖子(0 表示没有帖子,但如果您想分配,请在此处传递帖子 ID。更多参考在codex。)

这都是为了在 wordpress 中上传媒体。

注意:我还没有完成removing uploaded file 部分。我稍后会完成。

更新

帖子已更新。现在我们可以从上传器容器中删除上传的媒体元素。感谢this question and the answer我可以弄清楚实际的过程。

【讨论】:

  • 感谢您的帖子,非常详细的解释和最接近我需要的工作示例。但是我有两个问题,首先,当您从媒体列表中删除它时,它不会从网站上删除文件,其次它在 Chrome 中根本不起作用。我收到一个错误“主线程上的同步 XMLHttpRequest 已被弃用,因为它对最终用户的体验产生不利影响。”
  • 嗯,“Synchronous XMLHttpRequest”错误是针对jquery的同步文件传输方法的。我相信有很多资源可以解决这个错误。您需要在 delete_attachment 操作中挂钩您的自定义函数,以检查该媒体项目是否存在于您的内容的媒体列表中。如果是,则需要将其删除。
  • 我正在做一些改变以适应我的需要,XMLHttpRequest 来自 wordpress ajax,所以把 async: false 解决了这个问题,但是我现在发现了另一个问题,不是管理员的用户无法上传图片,我不知道我可能需要查看某种限制。
  • @zen_1991 我在wp_deleted_media 中有错字
  • @scooterlord 使用上面的代码上传新图片后,$newupload 将包含新上传图片的附件 ID。您将在成功回调的响应中得到它
【解决方案2】:

那些在为非管理员用户工作时遇到问题的人;请使用 admin-ajax.php 而不是 admin-post.php。

我遇到了一个奇怪的问题,即 admin-post.php 可以在我的本地服务器上为非管理员用户工作;但我的实时服务器拒绝让非管理员上传文件。 php 会回显整个页面而不是回显的值。

我用 admin-ajax.php 替换了 admin-post.php,上传工作非常棒。

我希望这会有所帮助。

【讨论】:

    【解决方案3】:

    除非我误解了问题,否则添加到此帖子的解决方案是不正确的。基本上,该解决方案不适用于未以管理员身份登录的任何人。我花了 30 分钟才解决这个问题,而且删除图像的解决方案不会将其从媒体库中删除。

    【讨论】:

    • 感谢您的评论。由于这是评论而不是答案,因此实际上应该转到评论部分。无论如何,我已经更新了答案,以便您可以使用它来允许您网站的访问者在您的服务器中上传文件,尽管我认为这不是很有帮助。最后,您的情况有什么问题?在我的情况下,文件删除得很好。你能解释一下,以便我修改我的吗?
    • 'delete'=>admin_url('wp_ajax.php?action=handle_deleted_media'),需要改成'delete'=>admin_url('wp_ajax.php?action=handle_delete_media'),
    猜你喜欢
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2020-09-30
    • 1970-01-01
    • 2016-09-03
    相关资源
    最近更新 更多