web-dev-qa-db-fra.com

WP_Query pour afficher le message d'une catégorie OR champ personnalisé

Je recherche un moyen d'afficher les messages appartenant à une catégorie spécifique ou s'ils ont un champ personnalisé. Si je spécifie les paramètres 'cat' => '9' et 'meta_key' => 'featured' dans les arguments de la requête, WP_Query renvoie des publications qui satisfont les deux conditions simultanément.

Que je ne veux pas Ce dont j'ai besoin, c'est d'afficher les publications si elles ont la catégorie 9 ou si elles ont un champ personnalisé featured.

Faites-moi savoir si cela n'a pas de sens. Je vais poster un exemple pour expliquer.

5
Robert hue

Vous pouvez essayer l’argument _meta_or_tax personnalisé dans WP_Query (PHP 5.4+):

$args = [
    'post_type'    => 'post',
    '_meta_or_tax' => true,        // <-- our new custom parameter
    'tax_query'    => [...],       // <-- our tax query
    'meta_query'   => [...],       // <-- our meta query
];

$query = new WP_Query( $args );

où nous utilisons le plugin suivant pour supporter cet argument personnalisé:

/**
 * Modify WP_Query to support 'meta_or_tax' argument
 * to use OR between meta- and taxonomy query parts.
 */
add_filter( 'posts_where', function( $where, \WP_Query $q )
{
   // Get query vars
   $tax_args    = isset( $q->query_vars['tax_query'] ) 
       ? $q->query_vars['tax_query'] 
       : null;
   $meta_args   = isset( $q->query_vars['meta_query'] ) 
       ? $q->query_vars['meta_query'] 
       : null;
   $meta_or_tax = isset( $q->query_vars['_meta_or_tax'] ) 
       ? wp_validate_boolean( $q->query_vars['_meta_or_tax'] )
       : false;

   // Construct the "tax OR meta" query
   if( $meta_or_tax && is_array( $tax_args ) &&  is_array( $meta_args )  )
   {
       global $wpdb;

       // Primary id column
       $field = 'ID';

       // Tax query
       $sql_tax  = get_tax_sql(  $tax_args,  $wpdb->posts, $field );

       // Meta query
       $sql_meta = get_meta_sql( $meta_args, 'post', $wpdb->posts, $field );

       // Modify the 'where' part
       if( isset( $sql_meta['where'] ) && isset( $sql_tax['where'] ) )
       {
           $where  = str_replace( 
               [ $sql_meta['where'], $sql_tax['where'] ], 
               '', 
               $where 
           );
           $where .= sprintf( 
               ' AND ( %s OR  %s ) ', 
                substr( trim( $sql_meta['where'] ), 4 ), 
                substr( trim( $sql_tax['where']  ), 4 )
           );
        }
    }
    return $where;
}, PHP_INT_MAX, 2 );

Ceci est une simplification non testée de mes réponses ici .

6
birgire