web-dev-qa-db-ja.com

カテゴリからの投稿を表示するWP_Query OR カスタムフィールド

カスタムフィールドがある場合、特定のカテゴリまたはに属する投稿を表示する方法を探しています。クエリ引数にパラメータ'cat' => '9''meta_key' => 'featured'の両方を指定した場合、WP_Queryは両方の条件を満たす投稿を返します。

私はしたくないです。カテゴリが9の場合、またはカスタムフィールドがfeaturedの場合は投稿を表示する必要があります。

意味がないのかどうか教えてください。例を挙げて説明します。

5
Robert hue

_meta_or_tax(PHP 5.4以降)でカスタムのWP_Query引数を試すことができます。

$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 );

このカスタム引数をサポートするために次のプラグインを使用します。

/**
 * 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 );

これは私の答えをテストしていない単純化したものです ここ

6
birgire