web-dev-qa-db-ja.com

分類法とメタ値によるポストの注文

Meta Valueで投稿を注文することは可能です

複数の値で投稿を注文することができます

そして、以下のコードのおかげで、分類法で注文することが可能です。

しかし、 分類法とmeta_value の順に並べ替えるには、以下のコードをどのように変更すればよいですか

functions.phpに追加された

function orderby_tax_clauses( $clauses, $wp_query ) {
global $wpdb;
$taxonomies = get_taxonomies();
foreach ($taxonomies as $taxonomy) {
    if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby']     ) {
            $clauses['join'] .=<<<SQL
LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb-    >term_relationships}.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
SQL;
            $clauses['where'] .= " AND (taxonomy = '{$taxonomy}' OR taxonomy IS NULL)";
            $clauses['groupby'] = "object_id";
            $clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
            $clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ?     'ASC' : 'DESC';
        }
    }
    return $clauses;
}

    add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 );

index.phpに追加された

<?php $args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => -1,
'meta_key' => '_EventStartDate',
'orderby' => 'taxonomy_cat',
'order' => asc
);
$the_query = new WP_Query( $args );

if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query-    >the_post(); ?>

etc. etc.

これを変更してもうまくいかない

'orderby' => 'taxonomy_cat meta_value',
3
Chris

あなたのコードには、

if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby'] 

設定した場合、複数の注文フィールドでコードが機能しなくなります。

'orderby' => 'taxonomy_cat meta_value'

$taxonomy == $wp_query->query['orderby']は決して真実ではありません。

さらに、注文する分類法を見つけることだけを目的としてすべての分類法をループすることは、パフォーマンスが低く、信頼性が低いことがわかりました。

だから私はあなたのコードを少し編集しました:あなたが分類学のために注文したいときあなたの引数は次のようなものであるべきです:

'orderby' => 'taxonomy.taxonomy_cat'

'taxonomy.'のおかげで分類法を簡単に認識でき、すべての分類法をループする必要はありません。

その後、WordPressは1つの引数のみを'order'引数として渡すことを許可します。そのため、複数の'orderby'引数を渡すと、期待される結果にならないことがあります。

だから私はあなたのコードを追加の引数'ordertax'を受け入れるように編集しました。もちろんこれはオプションなので、渡さない場合は 'order'引数が使用されます。 'orderby'に分類引数が含まれていない場合も無視されます。 'orderby'を渡さずに複数の'ordertax'引数を使用する場合、すべての引数は'order'引数(またはデフォルトの 'DESC')に基づく順序になります。

'orderby' => 'taxonomy.taxonomy_cat meta_value',
'order' => 'ASC'

を使用して"ORDERBY taxonomy_cat ASC, meta_value ASC"を意味します

'orderby' => 'taxonomy.taxonomy_cat meta_value',
'ordertax' => 'DESC'
'order' => 'ASC'

"ORDERBY taxonomy_cat DESC, meta_value ASC"を意味します。

今ここにコード:

function orderby_tax_clauses( $clauses, $wp_query ) {
  $orderby_arg = $wp_query->get('orderby');
  if ( ! empty( $orderby_arg ) && substr_count( $orderby_arg, 'taxonomy.' ) ) {
    global $wpdb;
    $bytax = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC)";
    $array = explode( ' ', $orderby_arg ); 
    if ( ! isset( $array[1] ) ) {
      $array = array( $bytax, "{$wpdb->posts}.post_date" );
      $taxonomy = str_replace( 'taxonomy.', '', $orderby_arg );
    } else {
      foreach ( $array as $i => $t ) {
        if ( substr_count( $t, 'taxonomy.' ) )  {
          $taxonomy = str_replace( 'taxonomy.', '', $t );
          $array[$i] = $bytax;
        } elseif ( $t === 'meta_value' || $t === 'meta_value_num' ) {
          $cast = ( $t === 'meta_value_num' ) ? 'SIGNED' : 'CHAR';
          $array[$i] = "CAST( {$wpdb->postmeta}.meta_value AS {$cast} )";
        } else {
          $array[$i] = "{$wpdb->posts}.{$t}";
        }
      }
    }
    $order = strtoupper( $wp_query->get('order') ) === 'ASC' ? ' ASC' : ' DESC';
    $ot = strtoupper( $wp_query->get('ordertax') );
    $ordertax = $ot === 'DESC' || $ot === 'ASC' ? " $ot" : " $order";
    $clauses['orderby'] = implode(', ',
      array_map( function($a) use ( $ordertax, $order ) {
        return ( strpos($a, 'GROUP_CONCAT') === 0 ) ? $a . $ordertax : $a . $order;
      }, $array )
    );
    $clauses['join'] .= " LEFT OUTER JOIN {$wpdb->term_relationships} ";
    $clauses['join'] .= "ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id";
    $clauses['join'] .= " LEFT OUTER JOIN {$wpdb->term_taxonomy} ";
    $clauses['join'] .= "USING (term_taxonomy_id)";
    $clauses['join'] .= " LEFT OUTER JOIN {$wpdb->terms} USING (term_id)";
    $clauses['groupby'] = "object_id";
    $clauses['where'] .= " AND (taxonomy = '{$taxonomy}' OR taxonomy IS NULL)";
  }
  return $clauses;
}

このように使用してください。

$args = array(
  'post_type'      => 'custom_post_type',
  'posts_per_page' => -1,
  'meta_key'       => '_EventStartDate',
  'orderby'        => 'taxonomy.taxonomy_cat meta_value',
  'ordertax'       => 'ASC',
  'order'          => 'DESC'
);

add_filter( 'posts_clauses', 'orderby_tax_clauses', 10, 2 );
$the_query = new WP_Query( $args );
remove_filter( 'posts_clauses', 'orderby_tax_clauses', 10, 2 );

分類クエリを含むWP_Queryと一緒に私のコードを(あなたのものと同じように)使うとうまくいかないかもしれないことに注意してください。

4
gmazzap