I am trying to change the path to my uploads directory when on this one specific page in my custom plugin. The page is a standard php page and not any specific type of post type page.

I have found numerous articles explaining the process, and I can see how it would work if this were a custom post type, but seeing as it's not the examples are not working as intended.

The URL to my custom page is as follows: http://localhost/custom-plugin/wp-admin/admin.php?page=custom-plugin-page&id=1.

the $_POST variable is dynamic based on the item that the user is editing.

I have come across the following and adjusted it to my needs:

function edd_load_upload_filter() {
    global $pagenow;

    if ( ! empty( $_POST['page'] ) && $_POST['page'] == 'custom-plugin-page' && ( 'async-upload.php' == $pagenow || 'media-upload.php' == $pagenow ) ) {
        add_filter( 'upload_dir', 'edd_set_upload_dir' );
add_action('admin_init', 'edd_load_upload_filter');

function edd_set_upload_dir($upload) {
    $upload['subdir']   = '/edd' . $upload['subdir'];
    $upload['path'] = $upload['basedir'] . $upload['subdir'];
    $upload['url'] = $upload['baseurl'] . $upload['subdir'];
    return $upload;

But as you can see, the function is checking if the post type is type 'download'.

From what I can tell, the $_POST variable is not empty on initial page load, but when the media modal is opened it is empty. Since it returns as empty inside the media modal, the path to the upload directory does not properly get set. If I remove the !empty( $_POST[ page'] ); check the path is properly adjusted, but then it gets adjusted across the entire site and not just on my custom page.

Not sure why the examples on the net all use some $_POST or $_REQUEST variable, but when I go to use it, it is empty so my function never fires. Any ideas?

  • 1
    My suggestion would be to run the upload_dir filter site-wide - dump $_POST, $_REQUEST, $_GET into your error log, upload something from your custom page and see if there's anything to work with to distinguish your custom page from other pages. error_log( print_r( $_POST, true ) );
    – Howdy_McGee
    Jun 30, 2015 at 16:46
  • Thank you for the suggestion, I'll give that a go and post some data back here
    – EHerman
    Jun 30, 2015 at 16:58
  • After some testing the $_POST, $_REQUEST and $_GET arrays are both very unhelpful and only provide details about the image that was uploaded: ie, attachment-id, filename and the nonce value. Now I'm unsure of how to proceed...
    – EHerman
    Jun 30, 2015 at 17:35
  • If that's the case then the conditional filter addition is probably the best path to explore. Hopefully I'll have more time to explore this in depth a little later.
    – Howdy_McGee
    Jun 30, 2015 at 17:38

2 Answers 2


After working on this for a bit and checking the GLOBALS variable for anything useful, it looks like the referring URL inside of the media modal is the same URL as my custom plugin page.

Using that and splitting it up a bit I was able to confirm that I am on the approrpriate page. I'm sure that there are other, more elegant solutions out there, but this is what I was able to come up with. I have tested and it seems to be working properly.

Here is my final solution :

    add_filter( 'admin_init' , 'check_if_we_should_change_upload_dir', 999 );
    function check_if_we_should_change_upload_dir() {   
            global $pagenow;
            $referrer = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '';
            if( $referrer != '' ) {
                $explode_1 = explode( 'page=' , $referrer );
                if( isset( $explode_1[1] ) ) {
                    $referring_page = explode( '&id=' , $explode_1[1] );
                    if( isset( $referring_page[0] ) && $referring_page[0] == 'custom-plugin-page' && ( 'async-upload.php' == $pagenow || 'media-upload.php' == $pagenow ) ) {
                        add_filter( 'upload_dir', 'alter_the_upload_dir' );

  function alter_the_upload_dir( $upload ) {
        $upload['subdir'] = '/custom-directory' . $upload['subdir'];
        $upload['path'] = $upload['basedir'] . $upload['subdir'];
        $upload['url']  = $upload['baseurl'] . $upload['subdir'];
        return $upload;

If anyone has any better solutions to checking, I am all ears!


  • This is quite good though WP has a function that gives you $_SERVER['HTTP_REFERER'] and does a bit more. Use wp_get_referer. Also I think the multiple explodes can be replaced with a concise, relevant strpos. e.g. strpos( wp_get_referer(),'custom-plugin-page' )
    – kakoma
    Sep 28, 2016 at 11:59

Thanks EHerman for your solution. My simplified version of your script would use the HTTP_REFERER in the upload filter directly:

function my_custom_upload_dir($path) {

  if(isset( $_SERVER['HTTP_REFERER'] )) {
    //parse url into array
    $referrer = parse_url($_SERVER['HTTP_REFERER']);
    // take the query part and parse it into array
    parse_str($referrer['query'], $queries);

   // check for anything that was in the query string of the current screen
   // you can use what ever you see in the wp-admin url before the upload frame opens    
    if( isset($queries['taxonomy']) ) {

        $mydir = '/taxonomy-files';

        $path['subdir']  = $mydir;
        $path['path']   = $path['basedir'].$mydir; 
        $path['url']    = $path['baseurl'].$mydir;  

  return $path; //altered or not

And to use the filter correctly

add_filter('wp_handle_upload_prefilter', 'my_upload_prefilter');
add_filter('wp_handle_upload', 'my_handle_upload');

function my_upload_prefilter( $file ) {
    add_filter('upload_dir', 'my_custom_upload_dir');
    return $file;

function my_handle_upload( $fileinfo ) {
    remove_filter('upload_dir', 'my_custom_upload_dir');
    return $fileinfo;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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