I have an Advanced Custom Fields field group on Edit User pages (user-edit.php
), containing an Image field (avatar). I aim to rename that uploaded filename to match the username of the on-page user.
My current code uses wp_handle_upload_prefilter
to catch the upload, and, to ensure the rename does not happen to all WP file uploads, I think I need to check that the upload field in question is my specific ACF Image...
In the below code, (1) I can successfully get the ACF field key and field for this check (check not fully implemented)...
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;
}
However, I'm struggling to (2) get the ID of the user on the user-edit.php page.
I have tried two methods found here on StackExchange...
1. wp_get_current_user
...
This...
$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']
This...
// 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.' );
}
But neither result in a user_id being located. It is always PHP Notice: Undefined variable: user_id
Is this because, whilst the Edit User page is still at user-edit.php?user_id=2
, the Media modal has somehow denied us the ability to get user_id
?
TL;DR - I need to get user_id
of currently-editing user on user-edit.php
whilst in a Media picker initiated by ACF. How can I do this?
Update with full answer
Sally CJ's answer is great. Her option #2 is optimal... use filter plupload_default_params
to pass variable to the AJAX Media uploader.
Then, when I do the user_avatar_rename()
on filter wp_handle_upload_prefilter
, the value of user_id
should be ready and waiting there...
My full code below. Big thanks to Sally.
/**
* ==============================================================================
* 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;
}
}