1

can anyone help me to sort Posts list in WP-admin by wp_posts table field like comment_status.

I know, that we can easy sort by meta field key, but cannot find any way how to sort by wp_posts table actual field.

If we dig in to source code of WP Query, we can find that there are allowed only these types of keys -

    $allowed_keys = array( 'name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count', 'type' );

https://github.com/WordPress/WordPress/blob/9d123aa326a908ff8ed6170e0fea5d85a4b1619f/wp-includes/query.php#L2719

Is there any way how to override them?

This is how I can sort by meta_key, but I need to sort by actual table field.

add_filter('manage_edit-post_sortable_columns', 'jepc_add_comments_column_table_sorting');
add_filter('request', 'jepc_column_sort');

function jepc_add_comments_column_table_sorting($columns) {
  $columns['comment_status'] = 'comment_status';
  return $columns;
}

function jepc_column_sort($vars) {
  if (isset( $vars['orderby']) && 'comment_status' == $vars['orderby']) {
    $vars = array_merge( $vars, array(
        'meta_key' => 'comment_status',
        'orderby' => 'meta_value'
    ));
}

return $vars;
}

Thanks.

2 Answers 2

1

Here's a way to add an extra Comment Status field to the posts list table:

add_filter('manage_post_posts_columns', function ( $columns ) 
{
    $_columns = [];

    foreach( (array) $columns as $key => $label )
    {
        $_columns[$key] = $label; 
        if( 'title' === $key )
            $_columns['wpse_comment_status'] = esc_html__( 'Comment Status', 'mydomain' );
    }
    return $_columns;
} );

add_action( 'manage_post_posts_custom_column', function ( $column_name, $post_id ) 
{
    if ( $column_name == 'wpse_comment_status')
       echo get_post_field( 'comment_status', $post_id );    

}, 10, 2 );

Here's how we can add a support for comment status ordering through the posts_orderby filter:

add_filter( 'manage_edit-post_sortable_columns', function ( $columns ) 
{
  $columns['wpse_comment_status'] = 'comment_status';
  return $columns;
} );

add_filter( 'posts_orderby', function( $orderby, \WP_Query $q ) use ( &$wpdb )
{   
    $_orderby = $q->get( 'orderby' );
    $_order   = $q->get( 'order' );

    if( 
           is_admin() 
        && $q->is_main_query() 
        && did_action( 'load-edit.php' )
        && 'comment_status' === $_orderby 
    )
        $orderby = " {$wpdb->posts}.comment_status " 
            . ( 'ASC' === strtoupper( $_order ) ? 'ASC' : 'DESC' )
            . ", {$wpdb->posts}.ID DESC ";

    return $orderby;
}, 10, 2 );

where we sub-order by the post ID.

Here's an example output:

status

PS: Since WordPress 4.5 (#35601) it's possible to filter WP_Query by comment_status and ping_status, so you should be able to implement such filtering for your the posts list table, as well

0

Awesome! I have modified code to meet my requirements.

// Sort columns by WP_posts table fields - comment_status and ping_status
add_filter( 'posts_orderby', function( $orderby, \WP_Query $q ) use ( &$wpdb ) {

    $_orderby = $q->get( 'orderby' );
    $_order   = $q->get( 'order' );

    if ($_orderby != 'comment_status' && $_orderby != 'ping_status') {
        return $orderby;
    }

    if( $q->is_main_query() && did_action('load-edit.php')) {
        $orderby = " {$wpdb->posts}.{$_orderby} "
            . ( 'ASC' === strtoupper( $_order ) ? 'ASC' : 'DESC' )
            . ", {$wpdb->posts}.ID DESC ";
    }

    return $orderby;

}, 10, 2);

For those who want to use the code in older versions of PHP.

add_filter( 'posts_orderby', 'jepc_comment_status_column_sort', 10, 2);

function jepc_comment_status_column_sort($orderby, \WP_Query $q) {

    global $wpdb;

    $_orderby = $q->get( 'orderby' );
    $_order   = $q->get( 'order' );

    if ($_orderby != 'comment_status' && $_orderby != 'ping_status') {
        return $orderby;
    }

    if( $q->is_main_query() && did_action('load-edit.php')) {
        $orderby = " {$wpdb->posts}.{$_orderby} "
            . ( 'ASC' === strtoupper( $_order ) ? 'ASC' : 'DESC' )
            . ", {$wpdb->posts}.ID DESC ";
    }

    return $orderby;

}

Thanks, you are awesome!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.