How to overwrite wp_unique_filename logic

We are having a problem where uploading images through the media upload tool sometimes times out. Using NewRelic, I’ve tracked it down to wp_unique_filename, which makes sense I guess because we have over 200,000 images.

What I figured I’d do is just skip that and automatically generate a hash to append to the end each filename on upload.

There does appear to be some decent documentation and questions around this but I just can’t seem to get it to work. I’ve added debug logging to see what’s happening and it always still calls the original functionality.

I’m still wrapping my head around filters and how they all work with built in functionality so it could be something VERY simple that I am doing wrong.

One important caveat – I am not doing custom uploads here, it is all through the WP Media Library.

Attempt #1

add_filter( 'wp_unique_filename', 'hash_filename', 10, 4);

function hash_filename($filename, $ext, $dir, $unique_filename_callback)  {
  error_log('in hash_filename');
  $new_filename = str_replace($ext, "", $filename);
  return $new_filename . "-" . md5(rand()) . $ext;
}

This still calls wp_unique_filename and THEN calls hash_filename. My log looks like this:

[22-Feb-2021 15:07:07 UTC] in wp_unique_filename
[22-Feb-2021 15:07:07 UTC] in original wp_unique_filename logic
[22-Feb-2021 15:07:07 UTC] in hash_filename

Attempt #2

function hash_filename($filename, $ext, $dir, $unique_filename_callback)  {
  error_log('in hash_filename');
  $new_filename = str_replace($ext, "", $filename);
  return $new_filename . "-" . md5(rand()) . $ext;
}

$overrides = array('unique_filename_callback' => 'hash_filename' );

My thought here was that if I set an $overrides var, it would somehow get picked up by media_handle_upload() or wp_upload(). I wasn’t too confident on this one because just seems like I’m missing something. It did not work either. My log shows:

[22-Feb-2021 15:13:06 UTC] in wp_unique_filename
[22-Feb-2021 15:13:06 UTC] in original wp_unique_filename logic

I’ve tried other variations of the above but I feel I’ve gotten to the point where I am just trying things that don’t make sense hoping one would work. Other variations include:

add_filter( 'unique_filename_callback', 'hash_filename' );
$overrides = array('test_form' => false, 'unique_filename_callback' => 'hash_filename' );
apply_filters('wp_handle_upload',$overrides);
// I felt this was promising but in looking up wp_handle_upload_overrides, it appears to not even be a thing? :(
$overrides = array('unique_filename_callback' => 'hash_filename' );
add_filter('wp_handle_upload_overrides',$overrides);

Can someone help please?

1 Answer
1

This doesn’t answer the specific issue I was having but does resolve the problem. The cause of my issue was that wp_unique_filename was taking longer and longer as the month went on when we had more images in our media library. We were already namespacing them with year/month dir structure.

I ended up adding a filter to override the upload dir to be year/month/day with the following code:

function upload_dir_filter($uploads)
{
    $day = date('d');
    $uploads['path'] .= "https://wordpress.stackexchange.com/" . $day;
    $uploads['url']  .= "https://wordpress.stackexchange.com/" . $day;
    return $uploads;
}
add_filter('upload_dir', 'upload_dir_filter');

This fixed our problem.

Leave a Comment