Jul
29
2009

How to stop WordPress 2.8 – 3.5 from deleting enclosures

[update: this bug seems to be fixed in WordPress 2.9 Beta 2]

[update: this bug is back in WordPress 3.0.1 and is still present in WordPress 3.4.2. It may have been in WordPress 3.0 and other versions as well]

After a couple of days of agony thinking that my WordPress database was seriously messed up, I discovered the bug that was causing enclosures to disappear turns out be considered a “fix/feature” by WordPress Org.

WordPress 2.8 not only places auto-enclosures like previous versions of WordPress, but it also auto-removes enclosures if there’s no link to the media file in the post body.

To keep your enclosures from disappearing in 2.8, you can place a link to the media file in your post body…of course this may be a redundant link or an unwanted link.

Why anyone would want auto-enclosures is beyond me. This functionality is really annoying and problematic. It also saves no time as entering the URL in the enclosure field and then using the enclosure to place a download link where the post is displayed is much more efficient…and logical…aren’t these templates we’re talking about? Why would we duplicate copy and code in every post?

So to fix this fix without having to place the redundant link to the media file, you need to edit the file at:
../wp-includes/functions.php

Simply delete or comment out lines 1164-1168. [Update: in 3.0.1 it’s lines 1184-1191] They look like:
foreach ( $pung as $link_test ) {
if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, $link_test . '%') );
}
}

Unfortunately of course this code will be added back again if you update WordPress (unless they see the error of their ways).

I would love to offer this as a free plug-in, but I don’t think there are any hooks for this in the WordPress API. I could be wrong as I’m not experienced at all in plug-in development for WordPress.

UPDATE: WordPress 3.3
I didn’t check this with each version, but in version 3.3 it’s line 1219 to 1226 which has this code:
foreach ( $pung as $link_test ) {
if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
$mid = $wpdb->get_col( $wpdb->prepare(“SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = ‘enclosure’ AND meta_value LIKE (%s)”, $post_ID, like_escape( $link_test ) . ‘%’) );
do_action( ‘delete_postmeta’, $mid );
$wpdb->query( $wpdb->prepare(“DELETE FROM $wpdb->postmeta WHERE meta_id IN(%s)”, implode( ‘,’, $mid ) ) );
do_action( ‘deleted_postmeta’, $mid );
}
}

UPDATE: WordPress 3.5
I didn’t check this with each version, but in version 3.4.2 it’s line 427 to 434 which has this code:

foreach ( $pung as $link_test ) {
if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
$mids = $wpdb->get_col( $wpdb->prepare(“SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = ‘enclosure’ AND meta_value LIKE (%s)”, $post_ID, like_escape( $link_test ) . ‘%’) );
foreach ( $mids as $mid )
delete_metadata_by_mid( ‘post’, $mid );
}
}

To find the code each time, I’m searching for “$pung as $link_test” and then reading the entire block of code. It changes, but it’s pretty easy to spot and comment out. Also it’s worth noting that this file won’t necessarily be changed with incremental updates. Still, I wish they would fix this.

Discussions about this issue are taking place on WordPress.org.

16 Comments »

RSS feed for comments on this post.


Leave a Reply

Powered by WordPress | Theme: Aeros 2.0 by TheBuckmaker.com