#StackBounty: #php #wp-admin #mysql #meta-query #sort Sortable admin column for one meta key with three possible meta values

Bounty: 50

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 OR NOT 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/>';
}


Get this bounty!!!

Bubble Sort Algorithm

Below is the code to do Bubble Sorting in Java for integer values

public class BubbleSort {
  
    // logic to sort the elements
    public static void srtbubble(int array[]) {
        int n = array.length;
        int k;
        for (int m = n; m >= 0; m--) {
            for (int i = 0; i < n - 1; i++) { k = i + 1; if (array[i] > array[k]) {
                    swap(i, k, array);
                }
            }
            print(array);
        }
    }
  
    private static void swap(int i, int j, int[] array) {
  
        int temp;
        temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
  
    private static void print(int[] input) {
          
        for (int i = 0; i < input.length; i++) {
            System.out.print(input[i] + ", ");
        }
        System.out.println("\n");
    }
  
    public static void main(String[] args) {
        int[] input = { 14, 21, 19, 62, 233, 142, 134, 10, 41 };
        srtbubble(input);
    }
}


Output:

14, 19, 21, 62, 142, 134, 10, 41, 233, 

14, 19, 21, 62, 134, 10, 41, 142, 233, 

14, 19, 21, 62, 10, 41, 134, 142, 233, 

14, 19, 21, 10, 41, 62, 134, 142, 233, 

14, 19, 10, 21, 41, 62, 134, 142, 233, 

14, 10, 19, 21, 41, 62, 134, 142, 233, 

10, 14, 19, 21, 41, 62, 134, 142, 233, 

10, 14, 19, 21, 41, 62, 134, 142, 233, 

10, 14, 19, 21, 41, 62, 134, 142, 233, 

10, 14, 19, 21, 41, 62, 134, 142, 233,