1

In a function fired from filter wp_handle_upload_prefilter, how can I utilise a variable obtained from previously firing action edit_user_profile?

My aim: on user-edit.php, when user uploads a file (ACF Image), get username of the user who is the subject of the form (not current user) and use that to rename the file.

My current idea:

  1. Using edit_user_profile, when Edit User loads, capture the ID to a variable.

  2. Feed that into the function fired by wp_handle_upload_prefilter, which does the file renaming, so that I can generate the required filename string.

However, I cannot manage to get this working in a way that doesn't throw an error inside the Media picker modal.

enter image description here

Options?:

I'm not sure if my use of globals is correct. I would prefer this method as it seems simplest.

Anonymous functions and using use?

Am I totally wrong to infer I can pass them this way, when the upload prefilter is probably focused on an Ajax modal? I assumed passing the variable would still be fine. Does the order matter?

    $myuserid = 5; // global scope - set 5 just to test flow



    // 1b. WHEN EDIT-USER.PHP LOADS, CAPTURE USER_ID
    function custom_user_profile_fields( $profileuser ) {
        $myuserid = $_GET['user_id'];
        echo '<h1>Foo We are Setting $myuserid to '.$myuserid.'</h1>';
    }
    // add_action( 'show_user_profile', 'custom_user_profile_fields' );
    add_action( 'edit_user_profile', 'custom_user_profile_fields' );




    // 2. WHEN TAKING AN UPLOAD, USE USER_ID TO GET OUR DATA & RENAME FILE

    // Filter entry, 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', 'my_pre_upload', 2, 1);

    function my_pre_upload($file, $myuserid){ // was function my_pre_upload($file, $myuserid) with 2 arguments{

        $user = get_userdata( $myuserid );

        // Renaming,  cf. https://stackoverflow.com/a/3261107/1375163
        $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;
    }

1 Answer 1

1

I'm not sure if my use of globals is correct. I would prefer this method as it seems simplest.

It's not.

The problem is that wp_handle_upload_prefilter is occurring in a completely separate AJAX request. It has no access to any PHP variables (global or otherwise) defined on user-edit.php.

If you hard-code the value into the file, the way you've done, then it will work, but that's only because the file is loaded for both requests. If you redefine the value in one hook it would still be the original value in the other, because that reassignment happened in a separate request.

Also, this won't work:

$myuserid = 5;

function my_pre_upload($file, $myuserid){}

my_pre_upload() will only receive arguments passed by the filter. And wp_handle_upload_prefilter only passed a single parameter, for the file information.

The only way to pass data from user-edit.php to wp_handle_upload_prefilter is to somehow modify the AJAX request for the upload to include the data you need. Then you can access it with $_POST.

The good news is that there is a filter, plupload_default_params, that will let you add parameters to the AJAX request for a media upload. So inside this filter, check if you're on a user edit screen or the profile screen, and if so, add the user ID to the parameters.

add_filter( 'plupload_default_params', function( $params ) {
    if ( ! is_admin() ) {
        return $params;
    }

    $screen_id = get_current_screen();

    if ( 'user-edit' === $screen_id ) {
        $params['user_id'] = $_GET['user_id'];
    } else if ( 'profile' === $screen_id ) {
        $params['user_id'] = get_current_user_id();
    }

    return $params;
} );

Then, in your wp_handle_upload_prefilter callback, check for this value and do your thing:

add_filter( 'wp_handle_upload_prefilter', function( $file ) {
    if ( isset( $_POST['user_id'] ) ) {
        $user_id = $_POST['user_id'];

        // Do what you want with the user.
    }

    return $file;
} );
1
  • Thanks for helping me understand. Commented Sep 17, 2021 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.