web-dev-qa-db-fra.com

Tri des colonnes avec méta-valeurs vides

J'essaie de trier mes colonnes de type de message personnalisé dans la zone d'administration. J'ai trouvé deux façons de le faire:

Au début, c’était ma façon de le faire, mais j’ai eu des comportements étranges. Si une méta-valeur n'est pas définie, le filtre supprimera la publication de la liste plutôt que de la trier.

add_filter('request', array($this, 'sort_columns') );
public function sort_columns( $vars ) { 
    if ( isset( $vars['orderby'] ) && 'startdate' == $vars['orderby'] ) {
        $vars = array_merge( $vars, array(
            'meta_key' => '_start_event_datetime',
            'orderby' => 'meta_value_num'
        ) );
    }
}

Dans l'espoir de résoudre ce comportement étrange, j'ai trouvé une autre façon de le faire, mais j'ai eu le même comportement.

add_action('pre_get_posts', array($this, 'sort_columns') );
public function sort_columns( $query ) { 
    $orderby = $query->get( 'orderby');  

    if( 'startdate' == $orderby ) {  
        $query->set('meta_key' , '_start_event_datetime');  
        $query->set('orderby' , 'meta_value_num');  
    }  
}

Comment puis-je trier mes publications sans méta-valeur à trier au lieu de les supprimer?

3
Scuba Kay

Le problème est qu’en définissant les articles à ordonner par _start_event_datetime, vous créez l’hypothèse implicite selon laquelle l’article aura cette méta. Cela signifie que la requête SQL générée par WordPress ne récupérera que les messages de votre type de message personnalisé avec cette méta.

Il y a deux solutions possibles à cela:

  • Remplacez votre requête actuelle par une méta requête légèrement plus complexe
  • Modifier la requête SQL pour utiliser une jointure externe plutôt qu'une jointure interne

Je vais vous montrer comment faire le premier car c'est la manière la plus sensée de le faire. La deuxième option serait judicieuse pour un tri plus avancé, comme le tri par plusieurs méta-clés ou les taxonomies. Je vous recommandons d'utiliser le crochet posts_clauses et de regarder ce billet de blog .

En utilisant une méta requête:

$query->set('meta_query',array(
    'relation'  => 'OR',
    array(
        'key'       => '_start_event_datetime',
        'compare'   => 'EXISTS'
    ),
    array(
        'key'       => '_start_event_datetime',
        'compare'   => 'NOT EXISTS',
        'value'     => 'bug #23268' // Allows WP-Librarian to run on pre-3.9 WP installs
    )
));
$query->set('orderby',   'meta_value_num');

Cette requête obtient toutes les publications avec ou sans la clé méta. Notez que la valeur de la condition NOT EXISTS est complètement abstraite et n’y existe que pour cause d’un bogue dans WordPress antérieur à 3.9.

4
kittsville