I've looked over 2 or 3 similar looking threads regarding sortable columns and the meta queries involved with making them work. None seem to resolve my exact problem.
I am using the pre_get_posts
filter to hook the sortable logic for an admin column. I have a post meta checkbox that I'd like to sort, it's key is _prioritize_s
.
When checked, the value is 'yes'
. If it has never been checked, then neither the key nor value exists. If it's been checked before, and then unchecked, the key exists, but the value is an empty string.
Here is how I'd like it to order:
- meta key
_prioritize_s
= 'yes', from the latest to oldest post - meta key
_prioritize_s
= empty string ORNOT EXISTS
, from the latest to oldest post
Here is what I have. It kind of works, but the date order doesn't seem to work properly and I need to group the NOT EXISTS
query with the one where the value could be an empty string?
class Featured_Admin_column {
public $column_names = [
'prioritized_post' => '_prioritize_s',
];
function init() {
$this->hooks();
}
function hooks() {
add_filter( 'manage_edit-post_sortable_columns', [ $this, 'create_sortable_columns' ] );
add_action( 'pre_get_posts', [ $this, 'set_meta_for_sortable_columns' ] );
}
function create_sortable_columns( $columns ) {
$columns['prioritized_post'] = 'priority';
return $columns;
}
function set_meta_for_sortable_columns( $query ) {
if ( ! is_admin() ) {
return;
}
$orderby = $query->get( 'orderby' );
if ( 'priority' == $orderby ) {
$query->set( 'meta_query', array(
'relation' => 'OR',
array(
'key' => '_prioritize_s',
'value' => 'yes',
),
//The 2 arrays below should be grouped together somehow...
array(
'key' => '_prioritize_s',
'value' => '',
),
array(
'key' => '_prioritize_s',
'compare' => 'NOT EXISTS'
)
) );
$query->set( 'orderby', 'meta_value date' );
}
}
Update: I've tried messing around with this some more, and thinking maybe WP considers blank values as null as well. When I tried putting the meta query on a page template so I could echo
out things and test before I mess with the admin columns, I tried reducing the meta query for 2 arrays instead of 3. I get both posts with and without the post meta _prioritize_s
but the date order is still out of whack despite using an array in the orderby
. What am I missing?
$test_sorting_by_priority = get_posts( [
'posts_per_page' => - 1,
'order' => 'DESC',
'orderby' => array(
'exists' => 'date',
'empty' => 'date',
),
'meta_query' => array(
'relation' => 'OR',
'exists' => array(
'key' => '_prioritize_s',
'value' => 'yes',
'compare' => 'EXISTS',
),
'empty' => array(
'key' => '_prioritize_s',
'compare' => 'NOT EXISTS'
),
),
] );
foreach ( $test_sorting_by_priority as $test ) {
$empty_or_null = isset( $test->{'_prioritize_s'}) ? $test->{'_prioritize_s'} : 'null';
echo $test->ID . ' ================== <b>' . $test->post_date . ' ===== ' . $empty_or_null . '</b> <br/>';
}
set_meta_for_sortable_columns
function?