web-dev-qa-db-fra.com

Meilleure pratique - Meta Query et post_clauses pour la commande "rejoindre la gauche"

Moreso une question pseudo-code que le code réel. J'ai quelques méta post personnalisé attaché aux pièces jointes et créé une colonne de table de liste pour cette méta. La méta est soit 1, soit null (non défini), mais j'essaie d'activer le tri pour ladite colonne.

Existe-t-il un moyen d'utiliser meta_query pour WP_Query pour essentiellement LEFT JOIN, où j'obtiens toutes les valeurs (1 ou null), puis je peux utiliser orderby=meta_value_num pour la commande?

La façon évidente de fonctionner fonctionnerait avec posts_clauses, en ajoutant un JOIN et en passant commande également - demandez-vous simplement si cela serait possible avec la fonctionnalité directe WP_Query!

Merci.

3
Eric Holmes

Vous pouvez le faire de toute façon!

En utilisant posts_clauses, écrivez manuellement votre instruction JOIN (en utilisant $ wpdb-> prepare () - soyez en sécurité!) Et ajoutez/personnalisez également la clause orderby.

En utilisant meta_query, plusieurs choses sont nécessaires. Tout d’abord, comme le mentionne kaiser, vous devez utiliser relation dans meta_query pour que cela fonctionne. Deuxièmement, même si meta_query est défini, vous devez toujours spécifier l'argument meta_key, sinon, orderby = meta_value ne fonctionnera pas. Je suppose que cela est dû au fait que vous pouvez avoir plusieurs jointures à la fois, ce qui pourrait utiliser différentes clés méta.

Voici comment je l'ai accompli:

function handle_my_sortable_column( $query ) {
    global $pagenow;
    if( is_admin() && 'upload.php' == $pagenow && 'my_meta_key' == get_query_var( 'orderby' ) ) {
        $query->set( 'meta_query', array(
            'relation' => 'OR',
            array(
                'key' => my_meta_key',
                'value' => null,
                'compare' => 'EXISTS'
            ),
            array(
                'key' => 'my_meta_key',
                'value' => '', // must be '' value, null does not work
                'compare' => 'NOT EXISTS'
            )
        ) );
        $query->set( 'meta_key', 'my_meta_key' ); // required for orderby
        $query->set( 'orderby', 'meta_value_num' );
    }
}
2
Eric Holmes

Vous pouvez utiliser pre_get_posts avec un rappel:

<?php
defined( 'ABSPATH' ) OR exit;
/** Plugin Name: (#102854) Order Posts by Foo */

add_filter( 'pre_get_posts', 'wpse_102854_orderby_foo' );
function wpse_102854_orderby_foo( $query )
{
    if ( 
        ! $query->is_main_query()
        OR ! is_admin()
        OR 'edit.php?post_type=YOUR_POST_TYPE' !== $GLOBALS['parent_file']
        // Other conditions that force an abort, Example:
        // OR 'foo' !== $query->get( 'some_query_var' )
    )
        return $query;

    $query->set( 'orderby', 'meta_value_num' );
    // etc.

    return $query;
}
2
kaiser