XML export posts from one single day

Enhance the native XML export – with a single day selection

Here’s one way to modify the native export with a select box, with all available days:

Single Day Export

Here we assume that there are not “huge” number of days to select from 😉 Otherwise we could use a different kind of user interface.

Step #1

First we can add the HTML for our single day filter by using the export_filters hook:

/**
 * Add our extra HTML
 */
add_action( 'export_filters', function() { 
?>
  <p><ul id="wpse-post-filters" class="wpse-export-filters">
      <li>
        <label><?php _e( 'Single day:' ); ?></label>
        <select name="wpse_single_day">
          <option value="0"><?php _e( 'Select a day' ); ?></option>
          <?php wpse_export_single_day_options(); ?>
        </select>
      </li>
    </ul></p>
<?php 
});

Step #2

Next we need to construct the wpse_export_single_day_options()function. We can simple use a modified version of the export_date_options() core function:

/**
 * Modification of the core export_date_options() function
 */
function wpse_export_single_day_options( $post_type="post" ) 
{
    global $wpdb, $wp_locale;
    $months = $wpdb->get_results( 
        $wpdb->prepare(
            "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month, Day( post_date ) as day
            FROM {$wpdb->posts}
            WHERE post_type = %s AND post_status != 'auto-draft'
            ORDER BY post_date DESC",
            $post_type 
        ) 
    );
    $month_count = count( $months );
    if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) )
        return;

    foreach ( $months as $date ) 
    {
        if ( 0 == $date->year )
            continue;
        $month = zeroise( $date->month, 2 );
        printf( 
            '<option value="%d-%d-%d">%d. %s %d</option>', 
            $date->year,
            $month,
            $date->day,     
            $date->day,
            $wp_locale->get_month( $month ),
            $date->year
        );
    }
}

Step #3

To place our HTML within the post filter section, we’ve to use jQuery to move it in the right place:

/**
 * Append our HTML to the post filter section
 */
add_action( 'admin_head', function() 
{?>
    <script type="text/javascript">
        jQuery(document).ready(function($){
            $('#wpse-post-filters').appendTo( $('#post-filters') );
        });
    </script>
<?php });

Step #4

Then we must take care of the database query. There’s no explicit filter for that but we can use the export_args filter, with a little trick:

/**
 * Modify the database queries, indirectly 
 */
add_filter( 'export_args', function( $args )
{   
    // User input
    $date = filter_input( INPUT_GET, 'wpse_single_day' );

    // Let's use DateTime to validate the Y-m-d input, 
    // See here http://stackoverflow.com/a/13194441/2078474
    $dt = DateTime::createFromFormat( 'Y-m-d', $date );

    // Check if the user input is a valid date:
    if( method_exists( $dt, 'format' ) && $Ymd = $dt->format( 'Y-m-d' ) )
    {
        // The from date for the db query:
        $args['start_date'] = $Ymd;

        // I think we can modify the end date, in the db query, with this little trick
        $args['end_date'] =  date( 
            'Y-m-d', 
            strtotime( 
                '-1 month', 
                strtotime( 
                    '+1 day', 
                    strtotime( $Ymd ) 
                ) 
            ) 
        );
    }
    return $args;
});

The demo plugin

I’ve added the whole plugin here on GitHub.

Leave a Comment