Elementor Pro makes it super easy to let your website visitors upload a file, using their native form widget.
By default, Elementor stores the file uploads in a folder on your server at /uploads/elementor/forms/
There are no options on the widget UI to change this location.
It can easily be changed with a few lines of code.
Here’s an example.
/**
* Change default location of Elementor's form file uploads
*
* @param $path
* @return string
*/
function zpd_change_elementor_form_upload_path( $path ){
//The folder name
$folder = 'elementor-file-uploads';
// Get the WordPress uploads folder
$wp_upload_dir = wp_upload_dir();
// This is the new path where we want to store the Form file uploads
$path = $wp_upload_dir['basedir'] . '/' . $folder;
/**
* Check to see if the folder already exists, create if not.
*/
if ( !file_exists( $path ) ) {
mkdir( $path, 0755, true);
}
return $path;
}
add_filter( 'elementor_pro/forms/upload_path', 'zpd_change_elementor_form_upload_path', 10, 1 );
/**
* Change default location of Elementor's form file uploads URL
*
* @param $file_name
* @return string
*/
function zpd_change_elementor_form_upload_file_url( $file_name ){
//The folder name
$folder = 'elementor-file-uploads';
// Get the WordPress uploads folder
$wp_upload_dir = wp_upload_dir();
// This is the new file URL path
$filename_arr = explode( '/', $file_name );
$url = $wp_upload_dir['baseurl'] . '/' . $folder . '/' . end( $filename_arr );
return $url;
}
add_filter( 'elementor_pro/forms/upload_url', 'zpd_change_elementor_form_upload_file_url', 10, 1 );
You can add this code to your theme’s functions.php file and the change will take place when you refresh a website page.
In this example, I am storing the files in a /uploads/elementor-file-uploads/ folder.
If you are storing sensitive data, perhaps add a .htaccess file into the folder to restrict access.
Update: Feb 2022
I’ve added another function that changes the file’s URL on the form submission.
Was this article helpful?
YesNo
29 Responses
Hi Wil!
Thanks for sharing this. Was looking all over the place to get this information.
Would you be so kind to share how this code would look like if you would just “normally” upload the files to the wp Media Library?
Thanks and all the best!
Florian
Hi Florian
You’re welcome.
Without the code and by default, Elementor stores all uploaded form files to the “/wp-content/uploads/elementor/forms” folder.
How to change the directory to the normal WordPress Media Library?
Best, Florian
Hey Florian
If you want the form uploads to go to the current media folder you would replace line 16
$path = $wp_upload_dir[‘basedir’] . ‘/’ . $folder;
with
$path = $wp_upload_dir[‘path’] ;
This will save to the current media folder which is usually /wp-content/uploads/YEAR/MONTH
Hope that helps you!
Wil.
Thanks for the info! This is very helpful but I have a question: my site has 3 different forms. Is it possible to change where the files are uploaded by each form? Each form has its own FormID. Thanks for everything!
Hi Mario
The code above sets the upload path for all forms.
In order to change this on a per-form basis, you would need to wrap the code in another hook during the form processing.
/**
* Change default location of Elementor’s form file uploads
*
* @param $path
* @return string
*/
function zpd_change_elementor_form_upload_path( $path, $folder ){
//Set default folder name if empty
if( empty( $folder ) ) $folder = ‘elementor-file-uploads’;
// Get the WordPress uploads folder
$wp_upload_dir = wp_upload_dir();
// This is the new path where we want to store the Form file uploads
$path = $wp_upload_dir[‘basedir’] . ‘/’ . $folder;
/**
* Check to see if the folder already exists, create if not.
*/
if ( !file_exists( $path ) ) {
mkdir( $path, 0755, true);
}
return $path;
}
add_filter( ‘elementor_pro/forms/upload_path’, ‘zpd_change_elementor_form_upload_path’, 10, 2 );
function zpd_change_elementor_form_upload_path_per_form( $record, $ajax_handler ){
$form_id = $record->get_field( ‘form_id );
switch( $form_id ){
case ‘blahblah1’:
apply_filter( ‘zpd_change_elementor_form_upload_path’, null, ‘elementor-form-uploads-‘ . $form_id );
break;
}
}
add_action( ‘elementor_pro/forms/process’, ‘zpd_change_elementor_form_upload_path_per_form’ );
Where is the $folder variable set at in the code to know if it should use the default folder name? im currently using your code to upload images to user folders based on username and would like to put specific images from specific forms into a specific folder.
Hi Jason.
The function function zpd_change_elementor_form_upload_path( $path ) on line 7 is used in an Elementor filter on line 26.
Filters normally pass at least one variable into the function. In this case on line 7, the function passes in $path which is the default path where Elementor saves form uploaded which equals “/uploads/elementor/forms/”.
The code overrides the default path and sets a new one.
You will need to add your own conditional code to test for cases where the default path is not changed.
I hope that helps.
Im getting the following Error when using the above code.
[12-Jun-2022 00:12:02 UTC] PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function zpd_change_elementor_form_upload_path(), 1 passed in /wp-includes/class-wp-hook.php on line 307 and exactly 2 expected in /wp-content/themes/oceanchild/functions.php:122
Make sure the line
add_filter( ‘elementor_pro/forms/upload_path’, ‘zpd_change_elementor_form_upload_path’, 10, 1 );
has 1 at the end as show above. This is the number of arguments passed into the function
zpd_change_elementor_form_upload_path( $path )
It looks like in your functions.php file, you are specifying 2 arguments but the hook only passes one which is $path.
The code works fine on my 3.7.1 Elementor Pro test site.
Thanks for the reply, in your code that you gave mario to do multiple locations based on form ID. You have 10,2 declared for upload path. This is the code I’m trying to use. I have your single form code working fine.
Oh, that bit of code.
I extended that to include an additional parameter called $folder so that a folder name could be passed through to it.
If you are using that code, make sure that all calls to “zpd_change_elementor_form_upload_path” have two parameters. Sounds like there is a bit of code where you are only passing one parameter.
I suspect that perhaps you have both lots of code in your functions.php file as you mentioned the single form code is working.
If that’s the case, then in the block of code for multiple folder locations change “zpd_change_elementor_form_upload_path” to “zpd_change_elementor_form_upload_path_multiple”, otherwise you are adding modifying the same filter further down the code to acce[t two parameters and the code above is only expecting one parameter.
Does that make sense?
appy_filter( ‘zpd_change_elementor_form_upload_path’, null, ‘elementor-form-uploads-‘ . $form_id );
Hello, i have disabled all code related to single form and only have the code you gave mario enabled. i noticed you have appy_filter and a few other typos but other than that everything is exactly the same and i still get the Too few arguments to function change_elementor_form_upload_path() error saying its only getting one argument. has any of the code changed since you posted it last year?
OK – new code. Note, this won’t work alongside the original code at the top of this post.
This code block grabs the internal Elementor form ID and stores the uploads in a folder in /uploads/elementor-file-uploads-form-id-XXXX where XXXX is the internal form ID (you can get that from the browser inspector.
/**
* Change upload folder based on Elementor Form ID
*
* @param $path
* @return string
*/
function zpd_change_elementor_form_upload_path_multi_form( $path ){
if( $_POST[ 'action'] === 'elementor_pro_forms_send_form'){
//The folder name
$folder = 'elementor-file-uploads-form-id-' . $_POST[ 'form_id' ];
}
else {
$folder = 'elementor-file-uploads';
}
// Get the WordPress uploads folder
$wp_upload_dir = wp_upload_dir();
// This is the new path where we want to store the Form file uploads
$path = $wp_upload_dir['basedir'] . '/' . $folder;
/**
* Check to see if the folder already exists, create if not.
*/
if ( !file_exists( $path ) ) {
mkdir( $path, 0755, true);
}
return $path;
}
add_filter( 'elementor_pro/forms/upload_path', 'zpd_change_elementor_form_upload_path_multi_form', 10, 1 );
/**
* Change default location of Elementor's form file uploads URL
*
* @param $file_name
* @return string
*/
function zpd_change_elementor_form_upload_file_url_multi_form( $file_name ){
error_log( print_r( $_POST, true ));
if( $_POST[ 'action'] === 'elementor_pro_forms_send_form'){
//The folder name
$folder = 'elementor-file-uploads-form-id-' . $_POST[ 'form_id' ];
}
else {
$folder = 'elementor-file-uploads';
}
// Get the WordPress uploads folder
$wp_upload_dir = wp_upload_dir();
// This is the new file URL path
$filename_arr = explode( '/', $file_name );
$url = $wp_upload_dir['baseurl'] . '/' . $folder . '/' . end( $filename_arr );
return $url;
}
add_filter( 'elementor_pro/forms/upload_url', 'zpd_change_elementor_form_upload_file_url_multi_form', 10, 1 );
how do I keep the original file name?
You can use the WordPress filter
wp_unique_filename
and create a function that detects the directory, either the default Elementor one ‘elementor/forms’ or your custom directory specified in my code.Then you can return the original file name using the $filename filter argument.
See: https://developer.wordpress.org/reference/functions/wp_unique_filename/ and https://github.com/elementor/elementor/issues/9859
Note: the github code has the wp_unique_filename filter arguments the wrong way round. They should be as per the developer reference (1st link).
Hi Wil,
Thanks for this interesting information,
I am looking for a way that will cause the files that the user uploads, not to be saved on the server and not to go through it at all (for not to overload the server), but in an external way like Google Drive or that the files will be sent directly to email.
Is there such a way?
Thanks,
Tal
Hi Tal
That is doable, but it’s quite a bit of development work to make that happen.
hi wil
then is there no solution for this please tell me how, I’m really a beginner..
thanks you
Hi Wil i have done exactly what you shared but mine still saves in the current directory
Lucas, are you running Elementor Pro?
Can you send me a temp screenshot of the code in your child theme’s functions.php, please?
Hi Wil,
Thanks for this so good information,
How can I save the file outside of the uploads folder like mydomine.com/folder?
It’s posible can help with this?
Thanks in advance!
Hey Tony,
The variable $wp_upload_dir[‘baseurl’] works out WordPress’ uploads folder from the root path of your installation.
You can replace that with the root filepath of your WordPress install to point to anywhere on your filesystem. Your cPanel or hosting equivalent will tell you where your root path is – if not – ask support.
It will likely be something like /users/blahblah/public_html/ or /home/blahblah/www/
Wil.
Hi Wil,
i have changed the path to a new folder but now when i store the url in a database or just view the submissions. the file path that is recorded still shows the original default url path. how can i change this. i have tried to hook into the url section but all it does is append what im wanting it to change the url to.
Jason, I’ve added another function that changes the file URL on the form submission. Make sure you use the same folder name as the previous function.
Regards,
Wil.
Would you be so kind to share how this code would look like if I want to upload the files to the S3?
Thanks
I haven’t implemented an Elementor S3 solution but it is possible using the Amazon S3 SDK an API.
Hey Wil! Thanx for this article!
I have a quastion. I want to send files directly to email or google drive (maybe using integromat – make), not just as a link but as an attachment. Is there such a way?
Hi Max
The easiest way to do that is to select “webhook” from the forms’ “Actions After Submit” list.
Then catch that form in Zapier or Make, processing the file path from the upload.
For more details see https://elementor.com/help/actions-after-submit/#:~:text=Your%20forms%20can%20also%20connect%20with%20services%20such%20as%20Zapier%2C%20via%20the%20Webhook%20action
Cheerz,
Wil.