How to Replace an Attachment in WordPress

Use this procedure to replace an attachment properly and according to best practices.

Problem

You need to replace an attachment with a new file. The attachment metadata must be updated according to the attributes of the new file.

Background

An attachment holds information about a file uploaded to the Media Library. When we upload a file to the library, two things happen:

  1. WordPress stores the file in the uploads folder
  2. WordPress adds records to the tables wp_posts and wp_postmeta. These records store metadata about the file, such as title, file name, file size, creation date, etc.

Plugin

The plugin Enable Media Replace is my preferred choice to replace attachments in WordPress. It is easy to use and it is top ranked in the WordPress Plugin Directory.

Step 1: Install and activate the plugin Enable Media Replace.

Step 2: Navigate to the Media Library and click Replace media on the desired entry.

Link added by the plugin Enable Media Replace to each entry in the attachment list.

Step 3: The Replace Media Upload screen is shown. Click Browse and choose a file on your computer. Change the default settings if desired and click Upload.

Form provided by the plugin Enable Media Replace.

Caching issue

Sometimes the plugin replaced an attachment successfully but the old version is still shown. This is especially true in the case of images. It happens because the file is stored in the browser cache.

Add the following code to solve this problem. It appends a number to the attachment URL and each time the attachment is replaced the number is increased.

/*
 * Adds a version number to the URL of an attachment to make it cache-safe.
 */
function ns_make_attachment_cache_safe($url, $post_ID){
    
    $version = get_post_meta($post_ID, '_ns_version_cf', true);
    $version = intval($version);
    return add_query_arg('ver', urlencode($version), $url);
}
add_filter('wp_get_attachment_url', 'ns_make_attachment_cache_safe', 10, 2);

/*
 * Updates the version of an attachment each time it is replaced.
 */
function ns_update_attachment_version($args){
    
    if(isset($args['post_id'])){
        $post_ID = $args['post_id'];
        $version = get_post_meta($post_ID, '_ns_version_cf', true);
        $version++;
        update_post_meta($post_ID, '_ns_version_cf', $version);
    }
}
add_action('wp_handle_replace', 'ns_update_attachment_version', 10, 1);

Further reading

I recommend the other tutorials in this series to learn more about managing attachments in WordPress.

Source code

The source code developed in this tutorial is available here.