在媒体选取器中,如何在wp_Handle_Upload_PreFilter过程中获取编辑用户页面的ID?

时间:2021-09-16 作者:Robert Andrews

我在编辑用户页面上有一个高级自定义字段字段组(user-edit.php), 包含图像字段(化身)。我的目标是重命名上传的文件名,以匹配页面上用户的用户名。

我当前的代码使用wp_handle_upload_prefilter 捕获上载,并确保重命名不会发生在all WP文件上传,我想我需要检查上传字段是否是我的特定ACF图像。。。

在下面的代码中,(1)我可以成功获取此检查的ACF字段键和字段(检查未完全实现)。。。

add_filter(\'wp_handle_upload_prefilter\', \'custom_upload_filter\' );

function custom_upload_filter( $file ) {

    // 1. GET SOURCE FIELD, COPIED FROM ACF\'S MEDIA.PHP

    $field = false;
    // Search for field key within available data.
    // Case 1) Media modal query.
    if ( isset( $_POST[\'query\'][\'_acfuploader\'] ) ) {
        $field_key = (string) $_POST[\'query\'][\'_acfuploader\'];

        // Case 2) Media modal upload.
    } elseif ( isset( $_POST[\'_acfuploader\'] ) ) {
        $field_key = (string) $_POST[\'_acfuploader\'];
    }

    // Attempt to load field.
    // Note the `acf_get_field()` function will return false if not found.
    if ( isset( $field_key ) ) {
        $field = acf_get_field( $field_key );
    }


    // 2. GET USER\'S ID AND USERNAME

    // Code here


    // 3. TEST RENAME CODE
    $file[\'name\'] = $user_id . \'and-everything-is-awesome-\' . $file[\'name\'];
    return $file;

}
然而,我很难(2)在用户编辑中获得用户的ID。php页面。

我试过了two methods found here on StackExchange...

1. wp_get_current_user...

$user_id = (int) $user_id;
$current_user = wp_get_current_user();
if ( ! defined( \'IS_PROFILE_PAGE\' ) )
    define( \'IS_PROFILE_PAGE\', ( $user_id == $current_user->ID ) );

if ( ! $user_id && IS_PROFILE_PAGE )
    $user_id = $current_user->ID;
elseif ( ! $user_id && ! IS_PROFILE_PAGE )
    wp_die(__( \'Invalid user ID.\' ) );
elseif ( ! get_userdata( $user_id ) )
    wp_die( __(\'Invalid user ID.\') );

2. $_GET[\'user_id\']

// If is current user\'s profile (profile.php)
if ( defined(\'IS_PROFILE_PAGE\') && IS_PROFILE_PAGE ) {
    $user_id = get_current_user_id();
// If is another user\'s profile page
} elseif (! empty($_GET[\'user_id\']) && is_numeric($_GET[\'user_id\']) ) {
    $user_id = $_GET[\'user_id\'];
// Otherwise something is wrong.
} else {
    die( \'No user id defined.\' );
}
但这两者都不会导致找到user\\u id。总是这样PHP Notice: Undefined variable: user_id

这是因为,当编辑用户页面仍处于user-edit.php?user_id=2, 媒体模式不知何故剥夺了我们获取user_id?

TL;医生-我需要user_id 上当前正在编辑用户的user-edit.php 在ACF启动的媒体选择器中。我该怎么做?

更新完整答案,Sally CJ的答案很棒。她的选项#2是最佳选择。。。使用筛选器plupload_default_params 将变量传递给AJAX媒体上载程序。然后,当我做user_avatar_rename() on过滤器wp_handle_upload_prefilter, 的价值user_id 应该准备好并在那里等待。。。

下面是我的完整代码。非常感谢莎莉。

/**
 * ==============================================================================
 *             RENAME UPLOADED USER AVATAR IMAGE FILE WITH USERNAME
 *    When an image is uploaded to Edit User form through an ACF field (field_6140a6da30a17),
 *    rename file with the username of said user.
 * ==============================================================================
 */

// 1. PASS USER_ID FROM USER-EDIT.PHP TO MEDIA UPLOADER, TO GET USERNAME FOR 
// cf. https://support.advancedcustomfields.com/forums/topic/force-an-image-file-upload-to-a-particular-directory/
// cf. https://wordpress.stackexchange.com/questions/395730/how-to-get-id-of-edit-user-page-during-wp-handle-upload-prefilter-whilst-in-med/395764?noredirect=1#comment577035_395764
add_filter(\'plupload_default_params\', function($params) {
    if (!function_exists(\'get_current_screen\')) {
        return $params;
    }
    $current_screen = get_current_screen();
    if ($current_screen->id == \'user-edit\') {
        $params[\'user_id\'] = $_GET[\'user_id\'];
    } elseif ($current_screen->id == \'profile\') {
        $params[\'user_id\'] = get_current_user_id();
    }
    return $params;
    });

// 2. ON UPLOAD, DO THE RENAME
// Filter, cf. https://wordpress.stackexchange.com/questions/168790/how-to-get-profile-user-id-when-uploading-image-via-media-uploader-on-profile-pa
// p1: filter, p2: function to execute, p3: priority eg 10, p4: number of arguments eg 2
add_filter(\'wp_handle_upload_prefilter\', \'user_avatar_rename\' );
function user_avatar_rename( $file ) {
    // Working with $POST contents of AJAX Media uploader
    $theuserid = $_POST[\'user_id\'];         // Passed from user-edit.php via plupload_default_params function
    $acffield  = $_POST[\'_acfuploader\'];    // ACF field key, inherent in $_POST
    // If user_id was present AND ACF field is for avatar Image
    if ( ($theuserid) && ($acffield==\'field_6140a6da30a17\') ) {
        // Get ID\'s username and rename file accordingly, cf. https://stackoverflow.com/a/3261107/1375163
        $user = get_userdata( $theuserid );
        $info = pathinfo($file[\'name\']);
        $ext  = empty($info[\'extension\']) ? \'\' : \'.\' . $info[\'extension\'];
        $name = basename($file[\'name\'], $ext);
        $file[\'name\'] = $user->user_login . $ext;
        // Carry on
        return $file;
    // Else, just use original filename
    } else {
        return $file;
    }
}

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

这是因为,当编辑用户页面仍处于user-edit.php?user_id=2, 媒体模式以某种方式剥夺了我们获得user_id?

在该页面上获取用户ID很容易,例如,您可以使用get_current_user_id() 要获取当前登录用户的ID,请使用$_GET[\'user_id\'] 获取正在编辑的配置文件的用户ID。

但问题是,默认的WordPress媒体上传程序会上传文件via AJAXwp-admin/async-upload.php 尽管在该页面上,您仍然可以获取当前登录用户的ID,但无法获取正在编辑的用户的ID,即上面的值user_id 参数,因为媒体上载程序不会;“转发”;这个user_id 值到async-upload.php.

因此,默认情况下,无法从wp_handle_upload_prefilter 运行在async-upload.php

但是,您可以执行以下操作之一:

使用wp_get_referer() 获取引用URL,然后读取user_id 从URL的查询字符串。

手动;“转发”;用户ID到async-upload.php, 可以通过plupload_default_params filter.

Working Examples

<对于上述第一个选项:

// Note: This is a simplified example. In actual implementation, you\'d want to
// check if the referring page is wp-admin/user-edit.php or wp-admin/profile.php

parse_str( parse_url( wp_get_referer(), PHP_URL_QUERY ), $args );
$user_id = $args[\'user_id\'] ?? get_current_user_id();

add_filter( \'plupload_default_params\', \'my_plupload_default_params\' );
function my_plupload_default_params( $params ) {
    // the admin page\'s file name, without .php
    $screens = array( \'user-edit\', \'profile\' );

    if ( is_admin() && in_array( get_current_screen()->id, $screens ) ) {
        $params[\'user_id\'] = ( defined( \'IS_PROFILE_PAGE\' ) && IS_PROFILE_PAGE ) ?
            get_current_user_id() : $_REQUEST[\'user_id\'];
    }

    return $params;
}
然后在函数中,只需使用$_POST[\'user_id\'] 获取用户ID。

相关推荐

ServerSideRender和Media Object:将图像数据对象传递给php呈现器的属性,即使它未设置

编辑:简单地说,我遇到的问题是,在js端保存为属性的图像数据对象(js中的imgDataObj)正在传递到PHP端,即使我没有在serversiderender组件中传递它,也没有在PHP渲染回调中侦听它。我有一个自定义脚本,可以创建具有自定义大小的图像集。我正试着把它放到一个街区里。ServerSideRender似乎是一条出路。我用它制作了一些块,但从来没有一块有图像。因此,用户可以从媒体库上传/拾取图像,并为每个断点设置自定义大小。块将图像的大小和ID号发送到PHP端。我们不需要整个图像对象。例如,