サポート » プラグイン » ACFプラグインのRepeater Fieldを使ったQuery制御

  • 投稿にプラグイン Advanced Custom Fields PROの、
    リピーターフィールドを使用してカテゴリとエリアを以下のように登録しています。
    categoryとareaはチェックボックスにしています。

    記事Aのリピーターフィールド
    name | category | area
    1 | a,b | B,A
    2 | b,c | A,C
    3 | b,c | A,C

    記事Bのリピーターフィールド
    name | category | area
    1 | b,c | A,C
    2 | b,c | B,C
    3 | a,c | A,C

    この記事をクエリーで絞り込む際に
    リピーターフィールド内のサブフィールドの値で絞り込みを行いたいです。
    具体的には、
    categoryが「a」でareaが「B」に該当する記事を絞り込み
    記事A(name1が両方該当)のみを絞り込む動きを表現したいです。

    プラグインのサイト内で近いコードを見つけて以下のように書いているのですが、
    これだと
    記事Bのname3のcategoryに「a」が入り、name2のareaに「B」が入っているため
    同一のnameに値が属していない記事Bもクエリーの対象となってしまいます。

    以下のコードを元に記事Aのみを絞り込む方法は無いでしょうか?

    対策として未入力用のサブフィールド(テキスト) fooをリピーターフィールド内に1つ追加して
    記事を更新したタイミングでcategoryとareaの値を結合してサブフィールドfooに登録。
    クエリーの絞り込みはfooを元に絞り込む方法は思いついています。
    ですが、出来ればサブフィールドを追加しないでクエリーによる絞り込みが理想です。
    いい方法はないものでしょうか・・・。

    アドバイスよろしくお願いします。

    
    function my_posts_where( $where ) {
    	$where = str_replace("meta_key = 'foo_%", "meta_key LIKE 'foo_%", $where);
    	return $where;
    }
    
    add_filter('posts_where', 'my_posts_where');
    
    // args
    $args = array(
    	'numberposts'	=> -1,
    	'post_type'	=> 'event',
    	'meta_query'	=> array(
    		'relation'		=> 'AND',
    		array(
    			'key'		=> 'foo_%_category',
    			'compare'	=> 'LIKE',
    			'value'		=> '11',
    		),
    		array(
    			'key'		=> 'foo_%_area',
    			'compare'	=> 'LIKE',
    			'value'		=> '22',
    		)
    	)
    );
    
2件の返信を表示中 - 1 - 2件目 (全2件中)
  • omarioooonさん

    整理させてください。

    まず、areaって言うのは、タクソノミーの名前でしょうか?それともカスタムフィールドで使用しているメタでしょうか。
    私も、複数のタクソミーにまたがってソートしたりするのですが

    以前は、カスタムフィールドでソートを行ってたんですが
    最近、タクソノミーだけで、ソートしてしまうことが増えています。

    私の場合、記事内でのソートが多いのですが(関連記事みたいな形)
    固定ページにソートのテンプレート組めば、カテゴリーみたいな感じでも動くと思います。

    書き換える時間なかったので、以前使ったソースそのまま載せてしまいます。
    すみません。

    どうしても、カスタムフィールドが必須の場合だと、複雑な場合はphpの配列(array)を使って取得してしまいます。

    
    <?php
     // 関連商品
    $taxonomy = 'itemcat';//カテゴリーを指定
    $taxonomy_2 = 'material';//追加分タクソノミー
    $categories = get_the_terms( $post->ID, $taxonomy );
    $categories_2 = get_the_terms( $post->ID, $taxonomy_2 );
     
    if ($categories) :
    $category_ids = array();
      foreach($categories as $individual_category) $category_ids[] = $individual_category->term_id;
       
    $category_ids_2 = array();
      foreach($categories_2 as $individual_category_2) $category_ids_2[] = $individual_category_2->term_id;
       
        $args= array(
          'tax_query' => array(
          'relation' => 'OR', //AND or OR                     
          array(
            'taxonomy' => $taxonomy,
            'field' => 'ID',//ID or slug
            'terms' => array( $individual_category->term_id ),//term_id
            'include_children' => true,
          ),//END relation
     
    //他のタクソノミーを追加する場合
          array(
            'taxonomy' => $taxonomy_2,
            'field' => 'ID',
            'terms' => array( $individual_category_2->term_id ),//term_id
            'include_children' => true,
            //'operator' => 'NOT IN'
             
          ),
           
        ),//END tax_query
     
        'post__not_in' => array($post->ID),//現在のIDを除外
        'showposts'=>6,//表示するPOST数
        'orderby' => 'rand',//ランダムに表示させる
    );
     
    $my_query = new wp_query($args);
    if($my_query->have_posts()) :
     ?>
     <div id="related_post">
      <h3 class="headline2"><?php echo '「 '.get_the_title().' 」の関連商品'; ?></h3>
      <ul class="clearfix">
       <?php
       while ($my_query->have_posts()) :
       $my_query->the_post();
       ?>
       <li class="clearfix">
        <a class="image" href="<?php the_permalink() ?>">
          <?php
          if ( has_post_thumbnail()) :
            the_post_thumbnail('size3');
          else :// no-has_post_thumbnail
            echo '<img src="'; bloginfo('template_url'); echo '/img/common/no_image1.gif" alt="" title="" />';
          endif;//END has_post_thumbnail
          ?>
        </a>
        <h4 class="title"><a href="<?php the_permalink() ?>"><?php the_title(); ?></a><span class="post-type">
        <?php
        //ポストタイプを定義
    $post_type = get_post_type();
    $post_type_obj = get_post_type_object($post_type);
      
      
    $custom_type = $post_type;
    //各種情報を取得
    $posttype_slug = esc_html($post_type_obj->name); //カスタムポストタイプのスラッグ取得
    $posttype_label = esc_html($post_type_obj->label ); //カスタムポストタイプの表示名
    $posttype_name = esc_html($post_type_obj->labels->singular_name ); //カスタムポストタイプの表示名
    $posttype_desc = esc_html($post_type_obj->description); //カスタムポストタイプの説明文
    $posttype_link = esc_url(get_post_type_archive_link($posttype_slug));
     
    echo $posttype_name;
         
        ?></span></h4>
       </li>
       <?php endwhile; ?>
      </ul>
     </div>
     <?php
     endif;//END have_posts()
     endif;//END タームが取得てきたら
     wp_reset_query();
      
     //END 関連商品
     ?>
    

    上の例は投稿ページ内に書いた例です(タクソノミーを2種類登録して使っています)

    name、category、area3つとも全てもカスタムフィールドで使用しているメタになります。
    厳密に言うとリピーターフィールドで登録したサブフィールドのメタです。
    またcategory、areaの2つはタクソノミーをカスタムフィールドのメタとして選択(登録)出来るようにしているだけで、
    postのタクソノミーとしてはセーブしないようにしています。
    ここでセーブしてしまうと
    リピーターフィールドで列をどんどん追加して、登録したタクソノミー全てが
    postのタクソノミーになってしまうと思うので、
    以下の現象にぶち当たってしまうかと。

    >記事Bのname3のcategoryに「a」が入り、name2のareaに「B」が入っているため
    >同一のnameに値が属していない記事Bもクエリーの対象となってしまいます。

    mura0403さんのように2つのタクソノミーだけの単純な絞り込みでしたら
    特に問題はないと思うのですが、
    今回私が望んでいる要件とは少し違っています。

    説明不足でわかりにくかったと思うので以下でもっと詳しく説明させていただきます。

    ・カスタム投稿タイプeventでイベントのシリーズ情報を数千件post登録する。
    ・カスタム投稿eventのpost内にそのイベントに属する個別のイベントを複数登録。
    ・個別のイベントには名前(name)、開催地(area)、カテゴリー(category)を登録する。
    ・アーカイブページでは開催地とカテゴリーを選択して絞り込み表示を出来るようにする。(メインクエリー)
    ・絞り込みはあくまで個別イベントについての情報で絞り込む。
    と言った内容です。

    さらに具体的に言うと、
    カスタム投稿タイプeventのAというイベントシリーズの中に、
    「第1回イベント」東京・神奈川、j-pop・hiphop
    「第2回イベント」北海道、reggae
    「番外編イベント」沖縄、演歌
    というような個別イベントを登録したいのです。

    そして絞り込みは個別イベントがもっている情報を元にクエリーを作ります。
    東京 – 演歌で絞り込んだ際にAのイベントシリーズが該当するのは困るわけです。
    東京では演歌のイベントをやっていないので。

    また並び替えはイベントシリーズ自体に登録されているカスタムフィールドの値をもとに行いたいです。

    一旦は個別イベントとイベントシリーズを別のカスタム投稿タイプとして登録して、
    一度裏側で個別イベントをget_postして絞り込みを行い、
    (mura0403さんが例に出したようなタクソノミーを使った絞り込みです)
    該当した数百〜数千の個別イベント情報を元にイベントシリーズのクエリーを用意したのですが、
    2重でクエリーを作ってるうえに、1度目の個別イベントをget_postする際には全件(1万件前後)を対象にする必要があるため
    とても重い処理になってしまい負担が大きくなってしまいました。

    そこで初回の質問で書いたような
    >対策として未入力用のサブフィールド(テキスト) fooをリピーターフィールド内に1つ追加して
    >記事を更新したタイミングでcategoryとareaの値を結合してサブフィールドfooに登録。
    >クエリーの絞り込みはfooを元に絞り込む方法は思いついています
    というような案しか現在思い浮かんでいない状態というわけです。

    説明が下手で申し訳ありませんが、
    引き続きアドバイスいただけるとうれしいです。
    よろしくお願いします。

2件の返信を表示中 - 1 - 2件目 (全2件中)
  • トピック「ACFプラグインのRepeater Fieldを使ったQuery制御」には新たに返信することはできません。