Last active
August 29, 2015 14:06
-
-
Save JodiWarren/72a876c7f2b7c10ab1cf to your computer and use it in GitHub Desktop.
Wordpress sort by meta key on date archive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
add_action( 'pre_get_posts', 'sort_by_custom_field' ); | |
function sort_by_custom_field( $query ){ | |
// Make sure we're on the front end, that we're dealing with the main query and that we're on the post type archive for the product custom post type. Also that at least a year is set. | |
if ( is_admin() || ! $query->is_main_query() || ! $query->is_post_type_archive( 'product' ) || ! $query->is_date() ) { | |
return $query; | |
} | |
// Could shrink this down a lot, but let's be readable. | |
$defaultYear = 2014; | |
if ( isset( $query['query']['year'] ) ) { | |
$queryYear = $query['query']['year']; | |
} else { | |
$queryYear = $defaultYear; | |
} | |
$outputFormat = 'Ymd'; | |
// The DateTime object stuff here looks scary if you're not used to it, but it's really not too bad. | |
if ( $query->is_year() ) { | |
$dateObj = DateTime::createFromFormat( '!Y', $queryYear ); | |
$queryStart = $dateObj->adjust( 'First day of the year' )->format($outputFormat); | |
$queryEnd = $dateObj->adjust( 'Last day of the year' )->format($outputFormat); | |
$queryValue = array( $queryStart, $queryEnd ); | |
$queryCompare = 'BETWEEN'; | |
} | |
// make sure it's a monthly query and that a month is set. | |
if ( isset( $query['query']['monthnum'] ) ) { | |
$queryMonth = $query['query']['monthnum']; | |
} | |
if ( $query->is_month() && $queryMonth ) { | |
$dateObj = DateTime::createFromFormat( '!Ym', $queryYear . $queryMonth ); | |
$queryStart = $dateObj->adjust( 'First day of the month' )->format($outputFormat); | |
$queryEnd = $dateObj->adjust( 'Last day of the month' )->format($outputFormat); | |
$queryValue = array( $queryStart, $queryEnd ); | |
$queryCompare = 'BETWEEN'; | |
} | |
// make sure it's a day query and that a day is set. | |
if ( $query->is_day() && isset( $query['query']['day'] ) ) { | |
$dateObj = DateTime::createFromFormat( '!Ymd', $queryYear . $queryMonth . $query['query']['day'] ); | |
$queryValue = $dateObj->format($outputFormat); | |
$queryCompare = '='; | |
} | |
// Sort by meta value: http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters | |
// | |
// Select items which have a meta_key of release_date, where it's between Jan 01 2014 and now. | |
// Times would have to be stored in the format YYYYMMDD for this method. | |
// | |
// Then order descending by release date and then ascending by title | |
$query->set( 'orderby' , array( 'meta_value_num' => 'DESC', 'title' => 'ASC' ) ); | |
if ( ! isset( $queryCompare ) || ! isset( $queryValue ) ) { | |
return $query | |
} | |
$query->set( 'meta_key' , 'release_date' ); | |
$query->set( 'meta_query' , array( | |
array( | |
'key' => 'release_date', | |
'value' => $queryValue, // this will either be the exact day or the range of dates applicable | |
'type' => 'DATE', | |
'compare' => $queryCompare, // This will either be BETWEEN or = | |
), | |
) | |
); | |
return $query; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is quite verbose for readability.