I’m writing a WordPress plugin to add a sortable column in the admin. The column needs to sort by date, based on two custom fields â one full month name (August, September etc.) and one four-digit year.
I’ve been following this excellent and extremely well commented tutorial but my SQL skills are virtually zero and I don’t know how to join the year field onto the query after the month field. I can make it all work if I use only one field that contains both the month and year, but that’s not how the site is set up.
How do I join the second field to give me a result in the format %M %Y or %M%Y so that I can convert it to a date?
The relevant part of the code:
switch( $orderby ) {
// If we're ordering by period
case 'period':
/* We have to join the postmeta table to include our date in the query. */
$pieces[ 'join' ] .= " LEFT JOIN $wpdb->postmeta wp_rd ON wp_rd.post_id = {$wpdb->posts}.ID AND wp_rd.meta_key = 'month'";
// Then tell the query to order by our date
$pieces[ 'orderby' ] = "STR_TO_DATE( wp_rd.meta_value,'%M %Y' ) $order, " . $pieces[ 'orderby' ];
The full code:
<?php
// Register the column
function month_column_register( $columns ) {
unset( $columns['tags'], $columns['comments'] ); // Gets rid of these columns
$new_columns = array();
foreach( $columns as $key => $value ) {
$new_columns[ $key ] = $value;
if ( $key == 'title' )
$new_columns[ 'month_column' ] = 'Period'; //Putting the month column after the title column
}
return $new_columns;
return $columns;
}
add_filter( 'manage_posts_columns', 'month_column_register' );
// Display the column content
function month_column_display( $column_name, $post_id ) {
if ( 'month_column' != $column_name )
return;
$month = get_post_meta($post_id, 'month', true);
$year = get_post_meta($post_id, 'year', true);
echo $month . ' ' . $year;
}
add_action( 'manage_posts_custom_column', 'month_column_display', 10, 2 );
function register_sortable ( $columns )
{
$columns['month_column'] = 'period';
return $columns;
}
add_filter('manage_edit-post_sortable_columns', 'register_sortable');
add_filter( 'posts_clauses', 'manage_wp_posts_be_qe_posts_clauses', 1, 2 );
function manage_wp_posts_be_qe_posts_clauses( $pieces, $query ) {
global $wpdb;
/* We only want our code to run in the main WP query AND if an orderby query variable is designated. */
if ( $query->is_main_query() && ( $orderby = $query->get( 'orderby' ) ) ) {
// Get the order query variable - ASC or DESC
$order = strtoupper( $query->get( 'order' ) );
// Make sure the order setting qualifies. If not, set default as ASC
if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) )
$order = 'ASC';
switch( $orderby ) {
// If we're ordering by period
case 'period':
/* We have to join the postmeta table to include our date in the query. */
$pieces[ 'join' ] .= " LEFT JOIN $wpdb->postmeta wp_rd ON wp_rd.post_id = {$wpdb->posts}.ID AND wp_rd.meta_key = 'month'";
// Then tell the query to order by our date
$pieces[ 'orderby' ] = "STR_TO_DATE( wp_rd.meta_value,'%M %Y' ) $order, " . $pieces[ 'orderby' ];
break;
}
}
return $pieces;
}
?>