Search code examples
phpwordpressfile-upload

Passing custom args for 'unique_filename_callback' in wp_handle_upload


I have an AJAX code that runs when a form is submitted with a file and I want to give that file a custom name before saving it to the uploads folder. For this, I want to use some data that was passed with the form but I cannot get the unique_filename_callback in wp_handle_upload to recognize that data. This is a snippet from my ajax code:

    $prod_name = $_POST['productName'];
    $orderId = $_POST['orderId'];

    function generate_filename( $dir, $name, $ext ){
        // $orderId and $prod_name are not being read by this callback
        $name =  $orderId . '__' . $prod_name . $ext;
        return $name;
    }

    $upload = wp_handle_upload( 
        $_FILES[ 'product_image' ], 
        array( 
            'test_form' => false,
            'unique_filename_callback'  =>  'generate_filename'
        ) 
    );

The file gets correctly uploaded, but the name turns out to be only '.png'. I am guessing that since the $ext arg is a default arg of this callback, so it knows the extension, but I cannot get the $orderId and $prodName to be passed in this callback. Thanks.


Solution

  • I guess the file generated would be named __.png instead of actually .png. This is because the code in your function references $orderId and $prod_name but they are not in the scope of the function.

    PHP is a local scope language (see Variable scope). Code within function do not have access to code outside. That's why $orderId and $prod_name are consider empty new variables within the function. Thus the result.

    To fix this, you should declare the variables within the function:

    
    function generate_filename( $dir, $name, $ext ) {
        $prod_name = $_POST['productName'];
        $orderId = $_POST['orderId'];
    
        // $orderId and $prod_name are not being read by this callback
        $name =  $orderId . '__' . $prod_name . $ext;
        return $name;
    }
    
    $upload = wp_handle_upload( 
        $_FILES[ 'product_image' ], 
        array( 
            'test_form' => false,
            'unique_filename_callback' => 'generate_filename',
        ) 
    );
    

    Note: This code would have risk if either $_POST['productName'] or $_POST['orderId'] is empty / undeclared in the POST request. You'd probably need to handle those cases.