Module Description
This module allows content editors to easily replace the source files associated with file-based media types (like "Document"). The replacement file overwrites the existing file, keeping the same filename and path, which is usually what content editors want to do when performing a file replacement.
This module operates on the media entity level, meaning the file replacement is done by accessing the edit form for a media entity that has a file source field on it. If you're using Drupal's media module for document management, then this is what you want.
Without this module, content editors would typically try and replace a file by editing the media entity, using the "remove" button on the file widget, and uploading a new replacement file with the same filename. However, this does not work as intended, as Drupal will append a number to the end of the replacement file, like "_1" or "_2", instead of actually overwriting the original. The only workaround is to delete the media entity, hope the site is configured to automatically delete unused files on cron runs, wait for that deletion to occur, and then upload a new document with the same filename.
Please see important notes below relating to caching and revisions before using this module.
Usage Instructions
* Enable this module
* Clear caches on your site
* Browse to the form display configuration for any file-based media types (Document, Image, etc).
* Enable the "Replace file" form display widget. It's best to place it directly beneath the existing "File" or "Image" widget.
* Edit an existing media of that type, and observe two changes:
* The "remove" button for the main file field has been removed.
* A new "Replace file" section is shown, which is used to upload the replacement
There are two options when uploading a replacement file.
When "Overwrite original file" is checked, the module will upload the replacement file to temporary storage, perform an operation to overwrite the original file with the uploaded replacement, and then update the file metadata stored in Drupal's database (file size, mimetype, etc).
If "Overwrite original file" is unchecked, the original functionality of the main file/image widget is maintained. A new file entity is created, and the media entity is updated to reference it. The old file entity is dereferenced, and may be marked as temporary (for deletion) if nothing else on the site is referencing it (depending on core's setting for make_unused_managed_files_temporary)
To prevent editors from using the replacement functionality from the core file/image widget, this module will also disable that functionality from the widget.
Important Caching Details Most likely, static files (.txt, .pdf, etc) served from your website will be cached by external caches for a long time, which means if you replace the contents of a file on your web server, users may not see the updated content. External caches include things like Varnish, a CDN, and web browsers.
You can control the behavior of external caches by emitting certain HTTP headers for static file responses. This cannot be configured in Drupal, because Drupal is not involved in serving static file assets. Your web server is.
There are some options:
* If you can, configure your web server to emit an ETag cache header for static file assets instead of a max-age header. This should prevent the need to manually purge old versions of files from caches.
* Set a short max-age header for static file assets. Drupal's default .htaccess file (which provides configuration for Apache) sets a max-age header to 2 weeks for static files. You can lower this to something like 5-10 minutes. You may need to inform your content editors that all users may not see the updated file contents for some time.
* Set a short max-age header for static file assets for browser caches, and a longer max-age header for proxy caches (Varnish, CDNs, etc). Then, use a modules like Purge and Purge File to have cached files purged from the proxy cache when they are updated on your site. There are still some issues with this approach, particularly around image style derivatives. Follow #2920332: Image style changes and purging and #2920332: Image style changes and purging for more details.
An ideal configuration involves having browsers cache the files for a short period of time (or not at all).
Impact on Revisions This module is not compatible with revisions on your media. One of the reasons Drupal core appends _1, _2, _3, etc to files when they are replaced (without using this module) is to support revision history. This allows you to revert to a previous version of the media and retain the original image from that revision. Since this module replaces the original file completely, there's no way to recover the original version.
Key Known Issues
* #3119626: Not working for translatable file fields (support Content Translation)
* #3109553: Media metadata fields are not updated after file is replaced
* #3131468: Only works with single file
Related Modules/Further Reading
* The core issue #2648816: Uploaded files are impossible to replace discusses this problem area in depth.
* The Media Entity Download module solves the same core issue in a different way. Instead of worrying about what the actual filename/path are on the site, documents are expected to be accessed via a special vanity URL based on the ID of the document (which never changes, even if replacing the source file). The downside to this approach is that the document is that Drupal is bootstrapped for every request for a public document, consuming valuable resources.
* The Media Entity File Redirect module does the same thing as Media Entity Download, but instead of having Drupal serve up the file directly, it just redirects the vanity URL to the real document URL. This is still problematic because someone may copy and paste the redirected URL to some other website, and that link may break in the future when a file replacement is performed.
* The File Replace module does something similar to this module, but it doesn't integrate with the Media module at all. Instead editors must access a special form for each individual file entity and perform the replacement upload there.
This module operates on the media entity level, meaning the file replacement is done by accessing the edit form for a media entity that has a file source field on it. If you're using Drupal's media module for document management, then this is what you want.
Without this module, content editors would typically try and replace a file by editing the media entity, using the "remove" button on the file widget, and uploading a new replacement file with the same filename. However, this does not work as intended, as Drupal will append a number to the end of the replacement file, like "_1" or "_2", instead of actually overwriting the original. The only workaround is to delete the media entity, hope the site is configured to automatically delete unused files on cron runs, wait for that deletion to occur, and then upload a new document with the same filename.
Please see important notes below relating to caching and revisions before using this module.
Usage Instructions
* Enable this module
* Clear caches on your site
* Browse to the form display configuration for any file-based media types (Document, Image, etc).
* Enable the "Replace file" form display widget. It's best to place it directly beneath the existing "File" or "Image" widget.
* Edit an existing media of that type, and observe two changes:
* The "remove" button for the main file field has been removed.
* A new "Replace file" section is shown, which is used to upload the replacement
There are two options when uploading a replacement file.
When "Overwrite original file" is checked, the module will upload the replacement file to temporary storage, perform an operation to overwrite the original file with the uploaded replacement, and then update the file metadata stored in Drupal's database (file size, mimetype, etc).
If "Overwrite original file" is unchecked, the original functionality of the main file/image widget is maintained. A new file entity is created, and the media entity is updated to reference it. The old file entity is dereferenced, and may be marked as temporary (for deletion) if nothing else on the site is referencing it (depending on core's setting for make_unused_managed_files_temporary)
To prevent editors from using the replacement functionality from the core file/image widget, this module will also disable that functionality from the widget.
Important Caching Details Most likely, static files (.txt, .pdf, etc) served from your website will be cached by external caches for a long time, which means if you replace the contents of a file on your web server, users may not see the updated content. External caches include things like Varnish, a CDN, and web browsers.
You can control the behavior of external caches by emitting certain HTTP headers for static file responses. This cannot be configured in Drupal, because Drupal is not involved in serving static file assets. Your web server is.
There are some options:
* If you can, configure your web server to emit an ETag cache header for static file assets instead of a max-age header. This should prevent the need to manually purge old versions of files from caches.
* Set a short max-age header for static file assets. Drupal's default .htaccess file (which provides configuration for Apache) sets a max-age header to 2 weeks for static files. You can lower this to something like 5-10 minutes. You may need to inform your content editors that all users may not see the updated file contents for some time.
* Set a short max-age header for static file assets for browser caches, and a longer max-age header for proxy caches (Varnish, CDNs, etc). Then, use a modules like Purge and Purge File to have cached files purged from the proxy cache when they are updated on your site. There are still some issues with this approach, particularly around image style derivatives. Follow #2920332: Image style changes and purging and #2920332: Image style changes and purging for more details.
An ideal configuration involves having browsers cache the files for a short period of time (or not at all).
Impact on Revisions This module is not compatible with revisions on your media. One of the reasons Drupal core appends _1, _2, _3, etc to files when they are replaced (without using this module) is to support revision history. This allows you to revert to a previous version of the media and retain the original image from that revision. Since this module replaces the original file completely, there's no way to recover the original version.
Key Known Issues
* #3119626: Not working for translatable file fields (support Content Translation)
* #3109553: Media metadata fields are not updated after file is replaced
* #3131468: Only works with single file
Related Modules/Further Reading
* The core issue #2648816: Uploaded files are impossible to replace discusses this problem area in depth.
* The Media Entity Download module solves the same core issue in a different way. Instead of worrying about what the actual filename/path are on the site, documents are expected to be accessed via a special vanity URL based on the ID of the document (which never changes, even if replacing the source file). The downside to this approach is that the document is that Drupal is bootstrapped for every request for a public document, consuming valuable resources.
* The Media Entity File Redirect module does the same thing as Media Entity Download, but instead of having Drupal serve up the file directly, it just redirects the vanity URL to the real document URL. This is still problematic because someone may copy and paste the redirected URL to some other website, and that link may break in the future when a file replacement is performed.
* The File Replace module does something similar to this module, but it doesn't integrate with the Media module at all. Instead editors must access a special form for each individual file entity and perform the replacement upload there.
Module Link
Project Usage
10573
Security Covered
Covered By Security Advisory
Version Available
Production
Module Summary
This module solves the problem of easily replacing source files associated with file-based media types while maintaining the same filename and path, which is typically not achievable in Drupal without this module.
Data Name
media_entity_file_replace