Last updated January 21, 2014. Created by arianek on December 1, 2009.
Edited by Fiable.biz, RLK, cedewey, davidneedham. Log in to edit this page.

The File module enables you to upload and attach files to content and to manage these uploads if you have the appropriate permissions. This module is responsible for validating file content and managing uploaded files. It also provides options for displaying file content.

As a site administrator you will be able to control what type of files can be uploaded and their maximum size.

File module provides its functionality by defining a File field type for the Field module. File attachments are defined at the content type level (or other entities). To learn how to define a field and add it to a content type, see Working with Field UI.

Uses

Adding a file field to a content type

Navigate to the "Manage fields" tab of the content type to which you wish to add the file field (Administer > Structure > Content types, and the link manage fields for your specific content type).

Select the field type file, give the field a label and machine name, click-and-drag it to the place you want to have it among your fields, and hit the save button.

As when adding any new field, you are first required to set the field specific settings. These apply for all places where you use the field. These cannot be changed per entity.

  • When checked, the Enable Display field option allows users to choose if a file should be shown when viewing the content.
  • The Files displayed by default option makes the display file option checked by default, when users upload files to this field.
  • The Upload destination by default only has the public files option available – making the files available right from the server (without Drupal checking any access). If you want to use private files, you must first change some settings at the file system administration page (Administer > Configuration > Media: File system). See below for details.

The next step is to set the field settings for this instance only. This can be changed between different content types (or other entities).

You can add validation options for the File field when you configure the content type. You must list all of the file extensions that the final user will need to be able to upload. The optional file directory where the files will be uploaded is a sub-directory of the file system path defined in the file system administration page (Administer > Configuration > Media: File system). You may specify a maximum file size for each file uploaded.


Managing attachment display

Once a file has been attached to content, you can specify whether it will be displayed in the list of attached files or not. Listed files are displayed automatically in a section at the bottom of the content; non-listed files can for example be embedded in your content, but are not included in the list. (Embedding a file in your content means you copy the path of the file and manually embed it where you want, for example, to insert in the content as a link tag. Note that the text format "Filtered HTML" by default refuses any image tags..)

Additional options for managing the display of the file list are available in the "Manage display" tab of the specific content type's administration page (Administer > Structure > Content types and the link field display for your content type).

Managing file locations and access

When you create a file field, you can specify the sub-directory of the site's file system where uploaded files for this content type will be stored. The site's file system paths are defined on the File system page (Administer > Configuration > Media: File system).

You can also specify whether files are stored in a public directory or in a private file storage area. Files in the public directory can be accessed directly through the web server; when public files are listed, direct links to the files are used and anyone who knows a file's URL can download the file. Files in the private directory are not accessible directly through the web server; when private files are listed, the links are Drupal path requests. This adds to server load and download time, since Drupal must resolve the path for each file download request, but allows for access restrictions.

The best practice for public files is to store them in the multi-site directory like:

sites/default/files

The default way to securely add a private directory for your files is to use a directory that can not be accessed directly by your web server, but can be accessed by Drupal. Ideally this directory should be located outside of your Drupal root folder.

The simple way to add a private directory for your files is to create a sub-directory under the public directory like:

sites/default/files/private

When you specify the private directory in admin/config/media/file-system it will automatically create the sub-directory & create a simple .htaccess file with Deny from all. This stops Apache from serving files from this directory. Make sure that you test this by adding a file to that directory and verifying that you can't browse there directly. If this isn't working, all files in this directory will be accessible to anyone who can guess the URL! Note that non-Apache web servers may need additional configuration to secure private file directories.

Whenever possible it's recommended that you choose a directory located outside of your Drupal root folder (or actually outside your web root), which may be tricky if you are on a shared host. If you do have access though, you can choose a private directory which will be on the same level as your web root directory (often called public_html or www or similar) using:

../private

Note: The “Default download method” has to be changed to private at admin/config/media/file-system. This will make Drupal apply checks to files.

Accessing Private Files

Once configured, files stored in the private directory are inaccessible via a direct link; however, if Drupal constructs a link to the file, the file will be accessible to anyone who can see the link.

For example: you have created a new content type with a file field which stores files in your site's private file directory. Next you create a node from this new content type and attach two new files. When the node is published links to both attached files are visible and anyone who can view the node may download the files. Now, if you unpublish the node, all attached files become inaccessible for download even if you use the direct link to the files that worked when the node was published.

Re-publish the node, and disable the "display" checkbox for one of the files. Save the node. Now one file is accessible for public download and the other is not accessible--even if you have the direct URL for the file that is not listed you will not be able to download this file.

For finer grained control of who can see/download attached files you will need an additional access control module. You may write a module yourself, or use a contributed module such as Content Access.

Technical Details

PHP configuration

For file uploads to work, PHP must be configured properly. The following PHP configuration variables may need to be set or configured, in your PHP php.ini file, .htaccess file, or settings.php files.

  • file_uploads = On must be set to "On"
  • upload_max_filesize = 24M can't be larger than post_max_size
  • max_input_time = 300 small values may cause timeouts for large file uploads
  • memory_limit = 64M small values may cause out of memory errors for large file uploads
  • max_execution_time = 180 small values may cause timeouts for large file uploads
  • post_max_size = 24M limits the size of input submitted to the website (including attached files)

Further Reference

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

The article above states "Ideally this directory [for private files] should be located outside of your Drupal root folder." However the default method described just below that puts the private directory below the public folder, thus seeming to not match the ideal.

Detailed instructions on how to set up the private directory in the ideal way would be useful.

I agree - the ideal isn't actually explained! How is one supposed to do it? Step-by-minute step please?

I think what is meant is, just like with all Drupal personalization, don't put files in the top/main/root Drupal directory, where all the core files live. Make sure you specify that files that are uploaded go somewhere in the 'sites' directory, such as 'sites/default/files' so that when you upgrade Drupal core, you can follow the traditional instructions for upgrading (i.e. backing up your sites directory and not overwriting it with the new Drupal core files), thus avoiding accidentally deleting all the files that were uploaded through your site.

And then for private files, I followed the instructions above as-is and it worked just as described. Drupal 7 creates an .htaccess in the 'private' directory and if you try to type in the URI to a file in that directory, you will get a 403 Forbidden message returned instead of the file. You will only be able to see the file via a node with appropriate permissions.

Hope that helps clarify.

From the original article: "The default way to securely add a private directory for your files is to use a directory that can not be accessed directly by your web server, but can be accessed by Drupal. Ideally this directory should be located outside of your Drupal root folder."

On a VPS I normally put the private directory one directory above the web root. On shared hosting, you may not have access to higher directories, which I'm guessing, is why the .htaccess method is also available.

Say you have drupal installed in /home/some_directory/www, then you could put your private directory in /home/some_directory. So your Configuration->File system->Private file system path setting would be /home/some_directory/private. In other words, you want private to be outside of www if possible.

Hope that makes sense.

Drupal 7 creates an .htaccess in the 'private' directory and if you try to type in the URI to a file in that directory, you will get a 403 Forbidden message returned instead of the file. You will only be able to see the file via a node with appropriate permissions.

Could you please describe in detail which permissions are needed?

My situation:
I am able to upload images (as administrator) to the private folder and to attach one to a page, but it won't be displayed on the page.
The files show up in the content media tab, but when trying to display the media (by double-clicking on the filename) only the tabs "View", "Edit", "Delete" and the filename are shown. The image is not visible!

This problem seems to be related to Media declared private no longer visible: Site broken. Do you have any suggestions?

Kind regards.

Using Drupal version 7.10 a new_content_type was added. New fields were added.
The Field Types and Widgets were set to "File" with "Public - accessible to all site users" access.
The uploaded files reside in a Private file directory /var/www/files.
The Access Control module was added, and the "role based access control settings" has checks in
"View any content" for the "anonymous user". Under the Organic groups global permissions,
the setting for View the new field for existing groups has been selected.
Links to the uploaded files appear, however, when the anonymous user selects the link to
download the file the following error appears:

Notice: Undefined index: field_name in og_field_access_field_access() (line 60 of
/var/www/html/sitename/sites/all/modules/og/og_field_access/og_field_access.module).

And the page shows:

Access Denied
You are not authorized to access this page.

Returning back to the pages added with the content type, then removing the uploaded
files allows the administrator to Manage fields in the content type and make it so
the Upload destination is Public files. The files can then be uploaded once more
and they are accessible by the anonymous user.

Steven Cory
Applications Analyst
Collaborative Studies Coordinating Center
Department of Biostatistics
The University of North Carolina at Chapel Hill

Hello all,

i am using drupal 7.
1. i need develop a page where the user can see the list of previously uploaded files.
2. and he can also share these files with other users.
3. the list of files will also display there status(shared/not shared)

can anyone guide me how to do this. i would like to develop a module for that. is it possible... will appreciate very if anyone answers on this

You may want to look into IMCE or at least continue the conversation there as there may already be a module to do what you're looking for.

I can't seem to remove any files or folders that got created during Token/URL testing while setting up a new content type.

I have logged in with a system admin and applied 777 permissions and still cannot delete.

What am I doing wrong? What is the right method to remove old folders/files?

Try to check if the owner of those folders is your user with whom you are trying to remove them. If the owner 'www-data', then you can change the owner of this folders to your user. If you cannot, try to user rmdir($dirname) function from your php file on your site. If you have files inside this folder, first you have to remove all files from inside.

Hi all,
I have a content type with a file field, set up with Upload destination = Private files.
My Private file system path = sites/default/files/private
An authorized user can create a node, and pick and upload a file.
Before saving the node, if he choses to "preview" the node, clicking on the attached file brings it up ok.
So far, so good.
However, once saved out, clicking on the attached file now results in the nasty: Access denied. You are not authorized to access this page".
User 1 (admin) can see fine, though.
Anyone has any idea about what could be wrong ?
Many thanks !

snoopy77 I would go over to my users and look at anonymous persmissions first.

''The secret though is just keep walking through life without analyzing it too much or clinging to it too much. Just walk on.'' - Marilyn Silverstone, Magnum Photographer & Buddhist Nun, b. March 9, 1929, October 1999.

I have discovered that even if the Drupal default file system settings is set to Public, you can set the File Field in a content type to Private so long as your Drupal settings have a private folder.

However, there is some issue with the core file field in Drupal 7 in that if the default Drupal file system is set to private and the file field in a content type is set to private, you will get the Access Denied message and 403 error. If you change Drupal config back to public, the file field is still private and will only pull the file from the private area.

I turned in a bug report, but easy enough to work around as the file field can be set to private and works with the private folder even if Drupal's default is public.

Granville


Accessing Private Files


...Re-publish the node, and disable the "display" checkbox for one of the files. Save the node. Now one file is accessible for public download and the other is not accessible--even if you have the direct URL for the file that is not listed you will not be able to download this file.

I don't believe this is correct. If "display" is unchecked, the link to the file doesn't appear in the published page. But the file is still accessible if you know the drupal path to it (for anonymous or authenticated users).

When I UNCHECKED Display for a private file, though not displayed, anyone CAN still DOWNLOAD the non-displayed private file if he/she remembered the previous drupal link, bug of the system or this article ?

Thanks for the great tutorial!
But how can I upload more than one file on one article? As I follow this tutorial, I only can upload one file.

I think this module can help you to upload multiple files at once. Please try this module: http://drupal.org/project/1115362

Doubt is the father of invention..... Hubmesh | download converter

When defining the file field just add:
'#attributes' => array('multiple' => 'multiple'), like this:
$form[$fieldset_name]['photos']['files'] = array(
'#type' => 'file',
'#title' => t('Upload photos'),
'#name' => 'files[]',
'#attributes' => array('multiple' => 'multiple'),
);

Before I just start guessing, does anyone have any experience putting the private and tmp folders in a non-web-accessible folder when running on IIS 7? Converting Windows paths to something a *nix-based system can understand seems to be different from project to project.

Hi,
in D7.12 I have a content type with 2 fields in it - the one is File and the other is Image. Both have the "Upload destination" set to "Private files".
In admin/config/media/file-system I have set "Private file system path" to "sites/default/files/private-files" and in it directory there is .htaccess file with "Deny from all" in it.
Files uploaded from File field are OK - they can be downloaded only from users with permissions for that content type.
But the files uploaded from Image field are seen from anyone via path system/files/styles/image_style_name/private/image_name.jpg. The url system/files/image_name.jpg brings the Access denied page.

What should I do to protect image files?
Thanks

subscribe

Progressing web site: http://www.bellitasty.com

When viewing a node with a file field that contains potentially unlimited files, is there some way to check off particular files and download them as an archive (zip, tar, etc.)? This seems like pretty basic functionality, but I don't see an option or module for accomplishing this.

A reply to an old question I know, but for future reference have a look at http://drupal.org/project/zipcart

I get an "Access denied" error for all users (with permissions) when trying to see uploaded (private) files and this error:
Warning: Cannot modify header information - headers already sent by (output started at /home/***/www/includes/common.inc:2607) en drupal_send_headers() (línea 1243 de /home/***/www/includes/bootstrap.inc).

Can someone help?

I have switched to using a private filesystem and even have the folder completely outside of the public_html folder (up one level) and Drupal creates a symlink to the files and makes a path of http://domain.com/system/files/folder/file.xxx and if you copy paste that from the source code (even anonymous users) can easliy download the file.

So my question is: what is the purpose of having a private filesystem if it is not private at all?
Second question is: How then, DO you protect files from being copied from source code and downloaded?

Make sure the node containing the file can't be viewed by anonymous users.

Thanks, it works !

But how to allow view node for anonymous users in order to view available fot download files and index them by Google, but block access to download them ( i.e. error 403 for non-authenticated user if they try to download files ) ?

For anyone struggling... the files will be private ONLY if the node they are associated with is NOT accessible to anonymous users. Even if you store the file as private, if the node is accessible to everyone, everyone can also download from sites/default/files/private

There are a number of modules that manage content permissions, or you can use the built-in taxonomy.

No, private files stored under alias SYSTEM ( system/files/folder/file.xxx )
They are NOT accessible to anonymous users even if user knows correct real path since this folder is protected by .htaccess.
System could also placed outside web-accessible area to ensure best possible protection.
But you shall define private folder under /admin/config/media/file-system (it is not activated by default)

Slovak thank you for the info! I found this to be exactly my problem, which has been kicking my butt for a while now. Finally I sat down today determined to figure it out and, after 2 hours of Google + trial + error, I found your post which resolved my issue!

My use case is on Drupal 7.14 multisite - I have a node where the body is readable by anonymous, but the PDF file is a private "members only" download. So - anyone can read the teaser, but only members can download the PDF. I thought I could make the file field private, while the body field was public, but this was not the case as anonymous users could still download the file!?

In short - even if a file field is set to a private directory - if anonymous users have permissions to "View Published Content" for that content type, that private file WILL be downloadable to the anonymous user role. Basically the file permission is inherited from the content type/node. If the content type itself is only viewable by an authenticated user, then file access will be denied to anonymous. If the content type is viewable by anonymous, all fields will be accessible by anonymous.

Try it - create a node with a private file; pdf, jpg, etc. Then publish that node so that anonymous can VIEW the node. Now anonymous can also download that private file, even/also by pasting in the "system/private/whatever.pdf" path.

Now go to the permissions page and uncheck "View Published Content" for anonymous users, then copy/paste your private file URL in the address bar - tada = access denied!

This lovely module made Drupal behave the way I expected - by making all private files private so that the body field is public, but the file field on the same node is now private/protected!

http://drupal.org/project/private_files_download_permission

Thanks!
--Tony

The field permissions module (http://drupal.org/project/field_permissions) allows you to set permissions on any field, not just private files. So, you could, for example, set your node text and image fields to be viewable by anyone (anonymous) and set the file field attached to the node to be viewable by only authenticated users for example.

ReggieW

It is a great idea, but I would like to know if this is just one of the many unproven theories. Is this in fact working in reality? I have seen so many modules that just don't respect the private file system.

An advice for all here. To understand the private file system, first start experimenting with a clean copy of Drupal and with only core modules and use plain role based protection to test it. This will exclude the influence of incompatible modules and takes away their confusion. When you have it working in core, then try adding related modules to see if it continues working like you want it and file bug reports if you find modules that are not respecting the core behaviour. There are many developers out there that never test their modules with the private file system simply because the never use it.

@drupleg
Thanks sir.
You saved my life. It took me several days and couldnt achieve it. We had to subscribe to longtail video CDN ! And it was only because I was testing video matters without installing content access BEFORE.
Thanks for your second mail especially (this one) : I couldnt believe the first time you said it! (as others here)...(strange isnt it ?)
But at the second I saw the light. It took me one minute to check it out live.
It will also save us a bunch of €€
Thanks again.

About Having a bundle of Files. as file with unlimited number of files.
the [node:field_file] returns "URL, URL , URL"
How to have this as a list of values.

Rajab Natshah
rajab.natshah.com

hi!
try it:
https://drupal.org/project/multiupload_filefield_widget
it allow to upload bulk files

SZL

In Drupal 6, to allow caching, I had the private file system enabled on a per folder basis by using .htaccess files with Apache rewrites, disabling rewrites in the folders where cache files were stored.

Here are the steps I needed to migrate the same system to Drupal 7.

I use this field type to allow visitors to download PDF files. However with PDF integration in Chrome (and possibly other browsers) instead of acting as a download the PDF is displayed in the active window. This is not what I want to happen, it would be far better if a new tab was opened for the PDF which would be an option if the download was a conventional link.

Is there a workaround to this?

Did you find a solution to this problem?

You can also just change the permission of your directory to make it private.
Personnaly i just apply 711 access to my /sites/all/files/myprivatedirectory

Ok, i implemented it but i get access denied on all files, by reading this topic i saw the access code is based on node's but my upload field is attached to a fieldable flag, what can i do to make my files visible for the right users?

thanks...

Running Drupal 7. I have two file fields set up: One is public, the other private. I need to be able to take a file which has been saved as a public file, and switch it to the private file field. And, vice-versa. Can someone provide some some advice on this? Thanks!

Hello all,

I use a template with blog pages content type (that includes file field off course).

When I upload an image the file is stored in the directory by default sites/default/files

When the page is displayed the file is accessed in the directory by default sites/default/files/styles/blog_post/public and then the image is not found.

If I add 'styles/blog_post/public' in the 'file directory' field of the 'managed fields' the file is uploaded in the right directory 'sites/default/files/styles/blog_post/public', but now the file displayed is accessed in 'sites/default/files/styles/blog_post/public/styles/blog_post/public'

Then where is defined the default location of the displayed files?

Regards