How to export posts with featured image

There’s not an easy way to modify the export query that runs under /wp-admin/export.php.

It doesn’t use the WP_Query or the get_posts() wrapper, instead it currently uses this query:

$post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" );

without explicit filters to it, though it’s possible to filter few settings through the export_args filter.

In ticket #28146 it’s suggested to rewrite it using get_posts() instead, but it’s not currently active.

Workaround

Here’s one type of a hack to only export posts with a featured image:

export items with featured image

Here are the main parts for such a plugin:

Step # 1

First we add the HTML for our filter’s settings:

/**
 * Custom Export Filters
 */
add_action( 'export_filters', function() { 
?>
  <p><ul class="wpse-export-filters">
      <li>
        <label><?php esc_html_e( 'With a featured image:', 'mydomain' ); ?></label>
        <input type="checkbox" name="wpse_with_featured_image" value="1">
      </li>
    </ul></p>
<?php 
} );

Step #2

Next we hook into export_wp to modify the export process:

/**
 * Modify the export query
 */
add_action( 'export_wp', function( Array $args )
{   
    // User input
    $with_featured_image = filter_input( INPUT_GET, 'wpse_with_featured_image' );

    // Check if we should activate our custom filter
    if( wp_validate_boolean( $with_featured_image ) )
        add_filter( 'query', 'wpse_modify_export' );

    return $args;
} );

where the wpse_modify_export() callback is defined as:

/**
 * Inject sub-query to find posts with featured image
 */
function wpse_modify_export( $query ) 
{
    global $wpdb;

    // Target the next posts query
    if( false === strpos( $query, "SELECT ID FROM {$wpdb->posts}" ) )
        return $query;

    // Remove filter callback
    remove_filter( current_filter(), __FUNCTION__ );

    // Inject sub-query to find posts with featured image
    $sql = " {$wpdb->posts}.ID IN ( SELECT DISTINCT post_id 
           FROM {$wpdb->postmeta} pm WHERE pm.meta_key = '_thumbnail_id' ) AND ";

    return str_replace( ' WHERE ', ' WHERE ' . $sql, $query );          
}

Hope you can adjust this to your needs.

Leave a Comment