【问题标题】:How to retrieve specific ACF repeater row with matching sub-field value如何检索具有匹配子字段值的特定 ACF 转发器行
【发布时间】:2017-01-15 13:43:27
【问题描述】:

我已经尝试和研究了几个小时,试图找到一种方法来让它发挥作用,但我只是没有任何运气。

所以我有几个不同的自定义帖子类型需要混合一下。让我尝试尽可能清晰和经济地解释它。

有 2 种自定义帖子类型,消息和校园。 (这是一个大型的多校区教会网站)。每个消息帖子都会有一些基于 Campuses 的转发器行(通过分类字段),每个 Campus 帖子都将尝试获取最新的消息帖子,并拉取特定的“校园”转发器行,以及该行中的相同字段值.

消息单个帖子的 ACF 转发器部分...(我们选择其中一个 Campus 帖子,然后手动输入发言人姓名和消息 URL)

所以目前,我在一个“校园”单一帖子中,试图查询并获取最新的消息帖子,该帖子正在运行。但后来我试图定位并仅提取消息帖子内部特定中继器行的值。消息中的转发器字段是 Campus Select(基于 Post Object 字段的选择框(在“campus”帖子类型上)和 2 个不同的文本字段。

为了进一步说明...消息帖子具有以下转发器数据: 中继器第 1 行:校园选择 - Troy(帖子),消息扬声器 - Danny Cox,消息 URL -(url A) 中继器第 2 行:校园选择 - 伯明翰(帖子),消息发言人 - Cliff Johnson,消息 URL -(URL B) ...并且多个校区将有动态数量的中继器。

所以我想要做的事情如下......在我的校园帖子中 - 例如“特洛伊” - 我想获取最新的消息帖子,进入转发器并找到带有“校园”的行选择”值。我想仅从该行返回消息扬声器 (Danny Cox) 和消息 URL (url A)。我不需要其他行的任何东西。

我当前的“最新消息”中有 2 个转发器行,这是我当前的查询:

<?php
  $args = array(
    'post_type' => 'messages',
    'posts_per_page' => 1
  );

  $latestMessageQuery = new WP_Query($args);
  if( $latestMessageQuery->have_posts() ) { ?>
    <?php while ($latestMessageQuery->have_posts()) : $latestMessageQuery->the_post(); ?>
      <?php if( have_rows('campus_message') ): ?>
        <?php while( have_rows('campus_message') ): the_row(); ?>
          <?php if( get_sub_field('campus_selector') == 'troy' ): ?>
            <?php the_sub_field('message_speaker'); ?>
          <?php else: ?>
            <?php the_sub_field('message_speaker'); ?>
          <?php endif; ?>
        <?php endwhile; ?>
      <?php endif; ?>
    <?php endwhile; ?>
  <?php }
  wp_reset_query();
?>

为了进行故障排除,我正在手动尝试获取“特洛伊”值“校园选择器”,而不是根据我当前的“校园”位置动态获取该值......

查询同时返回:“Cliff Johnson Danny Cox”(因为我有 2 个中继器行)。

如何在我的查询中仅返回:“Troy, Danny Cox, url A”?

【问题讨论】:

  • 鉴于我担心的数据之间的关系,设置存在问题。在您的示例中已经说过,您将在运行此查询之前获取校园的帖子名称,然后将 . . . == 'troy' 替换为该帖子名称。最后删除产生相同输出的相应else。但是,我会考虑几个替代方案。 1) 考虑不同的结构或 2) 使用自定义数据库查询 (codex.wordpress.org/Class_Reference/wpdb)
  • 嗨,Nathan,感谢您的回复...如上所示:“用于故障排除...”我可以动态获取帖子名称并将其拉入“... == 'troy'”少量。我可以解决那部分。我认为我无法更改结构,因为这已经是一个相当大的站点,并且为每个不同的校园提供一个 ACF 中继器的单个“消息”帖子似乎是更合乎逻辑的解决方案。 . 而不是每个校区都有 7 个不同的“信息”帖子。
  • 根据您的其他建议,对于我的技能水平,自定义数据库查询看起来非常复杂。你能举例说明这对我的情况有什么作用吗?

标签: wordpress custom-post-type advanced-custom-fields


【解决方案1】:

这不会遍历所有行,而只会在您的子字段与您的搜索匹配时读取该行。希望这会有所帮助

 while (have_rows('repeater_name')) {
      the_row();
      if (get_sub_field('sub_field') != $unique_key) {
        // not our row
        continue;
      }
      // will get here if this is our row
    $sub_field1= get_sub_field('sub_field1');
    $sub_field2= get_sub_field('sub_field2');
    }

【讨论】:

    【解决方案2】:

    我正在使用$wpdb global 提供更多的 SQL 直接解决方案。 通常情况下,我强烈反对“直接”使用 SQL,但在这种情况下,WP 元数据的结构和 ACF 存储的元数据在未来应该是稳定的,因为 ACF 流程是将字段存储为“正常”元/自定义字段。

    我发布此内容是因为它是一种非常简单且无冗余的方法,用于获取子字段值找到的特定 ACF 中继器行。
    ...当您有很多 ACF 中继器行时很有用。

    我将在选项字段组中向您展示一个关于中继器的示例,因为我认为它是最相关的。

    假设您有带有键/名称 your_option_name 的选项字段和带有键/名称 subfield_name 的子字段 - 请注意 \ 在某些部分转义,这是因为 SQL LIKE 使用 _ 作为
    一个特殊字符 - 意思是“任何单个字符”

      $query = 
     "SELECT option_name, option_value FROM {$GLOBALS['wpdb']->prefix}options"
    ." WHERE option_name LIKE ("
            ." SELECT"
            ." CONCAT( 'options\_your\_option\_name\_', CAST( REPLACE(option_name, 'options_your_option_name_', '' ) AS INTEGER ), '%' )"
            ." FROM {$GLOBALS['wpdb']->prefix}options"
            ." WHERE"
            ." (option_name LIKE 'options\_your\_option\_name\_%\_subfield\_name')"
            ." AND"
            ." (option_value = 'some subfield value')"
          ." LIMIT 0,1"
    ." )"
      ;
    
      $results = $GLOBALS['wpdb']->get_results( $query, ARRAY_A );
    
      if( !empty($results) ){
        foreach($results as $result){
          //do something with it :)
          echo $result['option_name'] . " => " . $result['option_value'];
          echo "<br>";
        }
    
      }
    

    此解决方案的主要缺点是,如果您有一些格式化的字段,则必须手动处理格式化,对于所见即所得的字段非常简单,只需使用the_content 过滤器,如
    echo apply_filters('the_content', $wysiwyg_stored_content);

    SQL 注释:它基本上搜索 prefix_main_key_NUMBER_subkey,然后从找到的键中删除 prefix_main_key_,所以现在只剩下 NUMBER_subkey => 如果您在 MySQL/MariaDB 中将字符串转换为 INTEGER 并且它以 INTEGER 开头,您将以这种方式获取 INTEGER... :)

    【讨论】:

      【解决方案3】:

      我在这个问题上从 ACF 支持获得了一些帮助,他们发送给我的以下代码得到了我的要求。

      <?php
      $args = array(
          'post_type' => 'messages',
          'posts_per_page' => 1
      );
      $current_campus_id = get_the_ID();
      
      $latestMessageQuery = new WP_Query($args);
      if( $latestMessageQuery->have_posts() ) {
          while ($latestMessageQuery->have_posts()) : $latestMessageQuery->the_post();
              if( have_rows('campus_message') ):
                  while( have_rows('campus_message') ): the_row();
                      if( get_sub_field('campus_selector') == $current_campus_id ):
                          the_sub_field('message_speaker');
                          the_sub_field('message_url');
                          break;
                      endif;
                  endwhile;
              endif;
          endwhile;
      }
      wp_reset_query();
      ?>
      

      【讨论】:

      • 虽然这可行,但似乎没有必要检索所有行并搜索它们......
      • 我完全同意你的看法。我的团队最终失去了这个项目(公司之间的一些愚蠢的政治),但是我很想知道你是否有另一个可行的解决方案来代替这个......?
      • 一种方法是直接转到 SQL,我通常不鼓励这样做......但这在未来应该是稳定的 :) 看我的回答
      猜你喜欢
      • 2019-05-22
      • 2023-02-22
      • 2021-11-23
      • 2019-01-26
      • 2019-05-24
      • 2017-05-10
      • 1970-01-01
      • 2023-02-10
      • 2019-11-16
      相关资源
      最近更新 更多